Reputation: 21178
I understand the Async nature of Silverlight, but one thing that constantly hampers my ability to program effective UIs is the race conditions and re-entrant problems caused by using objects which load data out of band. Is there any way to force out of band operations to be ordered as they are in the code?
For example imagine I have an object with a Load method whose sole job is to load data from a stream into a Textbox. If I call it Async as such:
Object.Load( targetbox1 );
Object.Load( targetbox2 );
Object.Load( targetbox3 );
The targetboxes will load but in any given order. If I reenter the load code for whatever reason then two loads try to take place at the same time and push into the same textbox leading to an exception. Most of these Objects support events and I could hook up a callback as such:
Object.Loaded ( s, e ) => {
Object.Load( targetbox2 );
Object.Loaded( s, e ) => {
...
}
}
Object.Load( targetbox1 );
But you see the problem with the nesting.
Is there any simple way to have these ops run in a serial fashion so that one call does not proceed until the prior has completed but doing so in a simple an intuitive fashion that can be applied across the board?
Upvotes: 3
Views: 350
Reputation: 189457
I wrote a couple of Blog articles here and here addressing this issue. The first describes in detail the internals of the solution, the second covers a how to use scenerio.
Here is a pseudo example base on your object Load/Loaded:-
AsyncOperation Load(YourObject subject, TextBox target)
{
return (completed) =>
{
EventHandler eh = null;
eh = (s, args) =>
{
subject.Loaded -= eh;
completed();
}
subject.Loaded += eh;
subject.Load(target);
}
}
With that your sequence would look something like this:-
IEnumerable<AsyncOperation> LoadTextBoxes()
{
yield return Load(subject1, textbox1);
yield return Load(subject2, textbox2);
yield return Load(subject3, textbox3);
}
and is executed with:-
LoadTextBoxes().Run(e =>
{
if (e != null)
{
//Something bad happened.
}
});
The main objective is that the sequence is guaranteed, can be as long as you like without nasty nesting, can use loops and you can even include other code to execute at specific points in the sequence.
Upvotes: 3