I'm starting a occasional series of postings on top things every
Silverlight
and WPF
developer should know. Originally, I was going to make this a
top-10 style list, but I'll keep that for my presentations, and
instead expand on it here, with one topic per post.

This one is about threading in Silverlight.

Ok, that subject sounds like a lot, but it's all pretty closely
related.

Both Silverlight and WPF have the concept of a UI thread.
Whenever you tie that thread up, you make your application
unresponsive. In Silverlight, if you're on a page with other
plug-ins, you make all the plug-ins unresponsive. (It's actually
per-process, but most modern browsers separate processes by
tabs)

Async Network Calls

In order to keep from tying up the UI thread, you have to
perform long-running processes on another thread. Often, but not
always, those processes are network calls. In Silverlight, all
network calls are async with no provision to handle them any other
way. This lets you off the hook threading-wise, but requires that
you understand how to chain those calls, and how to deal with
libraries that have IAsyncResult callbacks that return on different
threads.

Background Worker

For other processes, the BackgroundWorker is a great, simple, way to do
some background work while reporting progress to the UI. It takes
all the dispatching work away, so you can feel free to manipulate
the UI from the ProgressChanged and RunWorkerCompleted events. Do
not touch the UI from the DoWork event, as that is actually running
on a separate thread.

Of course, knowing how to set up event handlers using lambda
expressions is always helpful :)

Dispatcher

Sometimes, you spin off a thread of your own, or you have to
deal with some of the crufty stacks where the callbacks come back
on a different thread from the one that created the call. In those
cases, you need to use a dispatcher to make a call back to the UI
thread.

If the code is on a page, you can call the dispatcher property
and pass it a function to execute (yes, more lambda in this
example).

Timers

What about when you need to run something on a timer? The normal
timer classes require manual dispatching to do any UI updates.
However, Silverlight and WPF both have the DispatcherTimer class that handles all that
for you.

Of course, realize that what you're doing here is
interrupting the UI thread, not really running
anything on a separate thread. It's not suitable for anything
long-running and cpu-intensive, but rather something where you need
to execute on a regular interval. Clock UI updates are a perfect
example.

Threads

In general, I discourage folks from spinning off real threads.
Very few people understand how to efficiently work with threads, so
even if you're a threading genius, the person coming in after you
probably isn't. In most cases, the Background Worker will provide
you with what you need.

Conclusion

Threading in Silverlight and WPF is a little trickier than some
other technologies, because you have to worry about the UI thread.
My intention here was to both inform you that this trickiness
exists, and then show some ways of dealing with it.

I really try and get folks new to SL/WPF to stay away from "real" threading, that includes ThreadPool.

If you're in WPF, you can do more with the parallel extensions in most cases. I'd recommend looking at that before even thinking about custom threads. As we get more cores, it's going to be more and more important to just tell the CPU that we need to do something in parallel and let it figure out how many threads can be effectivly used on the machine.

If you really know threads enough to handle all the "other" stuff that comes along with them, like cancellation, updating shared data etc. then go for it. Otherwise, I strongly recommend the other approaches.

That said, I use a single separate thread in the Silverlight C64 emulator precisely because I do know why it's there and how to manage it :)

It's kind of misleading in your Dispatcher section to say "In those cases, you need to use a dispatcher to make a call back to the UI thread."

You don't really *need* Dispatcher, you just need to marshal your call back to the UI thread and the Dispatcher is one way to do that. I find SynchronizationContext just as easy to use as Dispatcher and SynchronizationContext has the added benefit of being unit testable without relying on the existence of a DispatcherObject somewhere in the current AppDomain. Unit testing ViewModels that use Dispatcher is problematic at best. Caveat: I mostly work in WPF, so I can't comment on Deployment.Current.

Otherwise, great article. Strategies for moving work off/on the UI thread is a skill that more devs should understand.

I will also add that the Dispatcher object is in the UI class for bot Silverlight/WPF. Therefore, when creating assemblies using this technique you will need to reference the System.Windows.UI (I think assembly) just to do Dispatcher. This is why SynchronizationContext is best practice for most scenarios.

Dispatcher has one less line of code that is why its always seen in blogs/articles. No need for this:
SynchrnizationContext syncContext = SynchronizationContext.Current;

sure you are right when saying "don't use threads unless you know how" - but I would put it rather: "learn how to use threads if you don't allready before using those" instead.
No use hiding from conurency these days - embrace and learn this stuff - sooner or later you have to and the TPL, parallel LINQ, etc. won't do anything for you if you don't understand the basic problems.

BTW: if you don't allready have, take a look at F# that comes with very powerful tools to help you get around some of the problemes with Sync.context etc. you mentioned (Async.SwitchToContext with a closure on the calling Sync.context comes to mind ;) )

Hello!
Thank you for useful and very detailed post. <a href="http://dotnetfollower.com/wordpress/2011/07/silverlight-for-windows-phone-7-how-to-check-if-the-current-thread-is-ui-one/">Here</a> a couple of words about Dispatcher.CheckAccess().

I found your article , when I was searching for thoughts and solurtions around threads and the Backgroundworker class for Silverlight. I want to express my Problem that I have and if you or an other guy who follows the article can help me to find a solution.
So my Use Case is as follows:
- The Application is able to export Framework Elements as Pdf file, using the OpenDialog class . Its page on the Pdf file is a rendered Image of each Framework Element. To do that I use the Telerik Function for exporting to Pdf. This function has the following signature: void Export(Raddocument document, Filestream stream). In this function the parameter document is the generated Pdf document and stream is the Filestream from the opendialog class.
- When the stream is written to the Hard disk after the User hits the Ok button in the Open Dialog the UI Window of my Silverlight application freezes for a while ( the time it needs for writing the file on the disk) .
- I tried to use according to your Blog article the Background calss and the Dispatcher , but I got Security exceptions...
- What can I do , so that the time it needs for the Stream to be written on the Disk , an indicator can inform the user with update progress without freezing ?

Interesting Thread!!! Thank you!
I wonder how if this can solve issue: I get data (a lot) from DB from a domain context (ria services, EF) and I wait, and wait, and wait, and even the busy control blocks.
Does anyone know how to make a request for RIA services with background worker (or any other solutions, smarter then the given idea).
Thank you for all who will try!
Thanks fo Pete for all the knowledge!

Pete - If I call a WCF service from a backgroundworker - where should the callback code be placed? In the _doWork event handler? When I do that it seems the thread never returns and the runworkercompleted event never gets tripped.

I'm not sure what you mean by where it should be placed. It's just a method, place it in your code and let Silverlight call it. If you're doing it as a lambda, you could define it in the dowork handler if you want, but try with it as a regular method first.

...Dammit. I see two spam messages up top that I missed. I hate it when those sneak through. The comment management system in this version of umbraco is not good for old stuff.

Thanks Pete - Turns out my backgroundworker was completing and firing the runworkercompleted event *before* the WCF service call returned. So a better question is when the service callback is fired, what thread is that on: the background thread that made the service call or the main UI thread? The behavior I'm seeing is that the background thread may be long gone by the time the service calls back. If that's true, then even though we call a service on a backgroundthread, the service callback should have access to page variables and UI Elements. Am I thinking straight?

I am using these things in my silverlight application but I am stuck some where.

I have a CommonSilverlight Class Library project which is used by difference silveright projects, and the CommonSilverlight Class library doesn't know whether the calling method is coming from UI Thread or Background Thread and in CommonSilverlight Class library we are calling some javascript method which is returning XML from server, If it comes from UI Thread then its working fine but if it comes from Background thread then there is a cross thread exception, we can not use Dispatcher.BeginInvoke method because it is a async method and method doesn't return me any xml because it fires after current method execution. we can not use SyncronizationContext here because SynchronizationContext must be declared in UI Thread.

Hello. I noticed your website title, "%BLOGTITLE%" does not really reflect the content of your site. When composing your website title, do you believe it's most beneficial to write it for Web optimization or for your readers? This is something I've been struggling with because I want great rankings but at the same time I want the best quality for my website visitors.

Comment on this Post

Your comment has been posted, thank you. (If your comment does not appear shortly, it was marked as spam.)

Pete Brown is a XAML and Blinky lights guy at Microsoft who focuses on Windows XAML (WinRT), WPF, Silverlight, .NET Micro Framework and other "code on the client" and "code on a device" technologies. This is his personal blog.
About Pete/Full Bio | Contact | About 10rem.net