Jerry Nixon @Work: Mango Sample: Async Work

Jerry Nixon on Windows

Thursday, November 17, 2011

Mango Sample: Async Work

imageThere are lots of things that take a long time - a politician's apology, dance recitals, and sometimes C# operations. if you don’t want your UI to freeze during these operations, it is important to make them asynchronous.

Option 1: The Event Pattern

One of the most common approaches is to create a void method that releases control and raises a Completed event when it is finished. Here’s how you implement that:

 

image
image
In the code above, look at MyLongActivity(). It’s not really a long activity, I just make it sleep for 5 seconds to simulate a long process. Now look at StartProcess(). StartProcess() is a wrapper that lets us call MyLongActivity() asynchronously. It starts MyLongActivity() on a background thread, then release control back to the caller.
See that BackgoundWorker? This is a great control. 1) It is available across every device and framework (making your implementations more consistent), 2) it is very simple to use, 3) it completes on the UI thread. That last part kills most developers.

Remember: we execute asynchronously on a non-UI thread so the UI continues moving. But, we can’t touch the UI thread from this background thread. If we try, we get this!:
image

Practice Safe Threading

First, the BackgroundWorker makes “returning to the UI thread” moot – it does it for you. But what if you want to anyway? Serious?! You nerds always want the details, don’t you? Okay. In Silverlight, we do this with the Dispatcher’s BeginInvoke() method:
image

Option 2: Callback Pattern

I am starting to like this pattern best. There are no events with callbacks. When the async operation is complete the callback is invoked. Since a callback is simply a method, your after-it’s-done logic is nicely packaged there (yes, like the completed event handler).
However, using a callback means you don’t have to differentiate multiple completed events with a user state object. When a callback is invoked, the context is known and sure. The only drawback is that it is somewhat more complex, at first. Only at first:
image
In the code above, just look how much less code there is and how much more control you get over the context. See Callback()? That method is invoked at the end of the async operation. There are no events, no event arguments. Just simple methods.

Conclusion

You must choose an asynchronous strategy. Silverlight requires it for resource requests and your users will require it for a good experience. My preference is starting to be the callback pattern, but I have used the event pattern for years. You have to pick one. Well, no you don't. You can use them both. Best of luck!