This project has moved. For the latest updates, please go here.

Silverlight LazyLoad should lock and initialise the fieldmanager

Jul 7, 2011 at 5:30 PM
Edited Jul 7, 2011 at 10:57 PM

The lazyload implementation at the moment doesn't lock - I had a strange issue where occasional crashes would happen with (catastrophic apparently!) failures.

This was due to the current lazyload implementation

The first time an object queries a property, the lazyload checks if the field exists and then begins an async load of the child object, however, subsequent calls to this property check if the field exists on the fieldmanager, and since nothing is done in the first check (and there is also no locking) another load is kicked off

This can result in multiple loads hitting the objects when the user is mid-edit and can cause binding errors and crashes

// Proposed implementation

// Define a lock for this property
private object InvoicesLock = new object();

///
/// Gets the Invoices ("lazy load" child property).
///
/// The Invoices.
public InvoiceCollection Invoices
{
get
{
#if SILVERLIGHT

// Lock here to prevent any other async threads from hitting the prop whist the fieldmanager is being initialised
lock(InvoicesLock)
{
if (!FieldManager.FieldExists(InvoicesProperty))
{
// Here the field manager field will still not exist if the property is queried again so load a default
 value (null or possibly default(type)) during the lock, subsequent threads will have to wait until 
this lock is released to query the fieldmanager
		LoadProperty(InvoicesProperty, null);

if (this.IsNew)
{
InvoiceCollection.NewInvoiceCollection((o, e) =>
{
if (e.Error != null)
throw e.Error;
else
{
// set the property so OnPropertyChanged is raised
Invoices = e.Object;
}
});
return null;
}
else
{
InvoiceCollection.GetInvoiceCollection(ReadProperty(SalesOrderIDProperty), (o, e) =>
{
if (e.Error != null)
throw e.Error;
else
{
// set the property so OnPropertyChanged is raised
Invoices = e.Object;
}
});
return null;
}
}
else
{
		// After the initial property query this will be hit by all subsequent threads
return GetProperty(InvoicesProperty);
}
} // end of lock
#else
if (!FieldManager.FieldExists(InvoicesProperty))
if (this.IsNew)
Invoices = InvoiceCollection.NewInvoiceCollection();
else
Invoices = InvoiceCollection.GetInvoiceCollection(ReadProperty(SalesOrderIDProperty));

return GetProperty(InvoicesProperty);
#endif
}
set
{
LoadProperty(InvoicesProperty, value);
OnPropertyChanged(InvoicesProperty);
}
}
Coordinator
Jul 8, 2011 at 11:54 PM
Edited Jul 8, 2011 at 11:55 PM

Hi Charleh,

I just reproduced the code from the ebooks. I never layed my hands on any piece of code that uses child loazy load asynchronously, either WPF either Silverlight. Can you post a sample? I mean a sample of a workig application UI and BD included.

Jul 11, 2011 at 10:42 AM

Hi Tiago,

I can't put any of my current project up as it's sensitive: I'll put together a demo of the lazyload, mostly the problem is just many LazyLoad operations being started by property accessing (a few objects look at the same property and because of the lack of lock and lack of initialising the fieldmanager every single call starts a new dataportal operation!)

I'll try to get a demo done today if I get time

Thanks

Jul 11, 2011 at 1:52 PM

Added a new work item with the project attached: let me know if any issues getting it running (it's VS2010, SQL2005)

http://cslagenfork.codeplex.com/workitem/595

Coordinator
Jul 12, 2011 at 8:03 AM
Edited Jul 12, 2011 at 8:09 AM

Hi Charleh,

I'm having trouble running your solution, namely the LazyLoadTest.Web project - some problem with mu XP settings.

Will try it on a brnad new Windows7 VM and get back to you.

Jul 12, 2011 at 10:38 AM

Hi Tiago,

If you still have trouble, I've added a screenshot to the work item so you can at least see the issue. It shows the WCF calls using WebDevHelper which looks at the http calls from the browser

Thanks

Coordinator
Jul 25, 2011 at 1:22 AM

Hi Charleh,

I'd like to draw tour attention to a thread in the forum http://forums.lhotka.net/forums/p/3679/49386.aspx#49386 where Rocky debates the problem and even adds a sample to the trunk at \Samples\Silverlight\cs\LazyLoad

Regards

Tiago

Jul 25, 2011 at 10:17 PM

Hi Tiago,

I've replied to that thread. Looking at the code from the eBooks, it looks like they would have the same issue. I think it's rare that two UI elements binds to the same property, but it can happen, so I think this is something to look at. I've not had any issues with edit levels in my project, but I don't have multi level undo happening, so possibly this is something that might not work with my implementation. I'd have to do some tests and look at the thread on lhotka.net in more detail

Thanks

Jul 27, 2011 at 6:07 PM

A mistake on my part, the lock isn't neccessary as Rocky says - there is only one thread operating in the UI context that would query the properties - but certainly the initialisation of the fieldmanager is important. I've updated the issue tracker