Getting back to the UI Thread in Silverlight 2 Beta 2
The problem
Silverlight 2 Beta 2 has changed the concurrency model for asynchronous communications. In Silverlight 2 Beta 1, asynchronous requests always returned on the UI Thread. This was convenient, since updates to the user interface can only be done via the UI thread. As of Silverlight 2 Beta 2, asynchronous callbacks are fired in worker threads that come from a thread pool: although this potentially allows for better performance via concurrency, it increases the risk for race conditions between callbacks – more importantly, some mechanism is necessary to make code that updates the user interface run in the UI thread.
A solution
It’s straightforward to execute a function in the UI thread by using the Dispatcher property of any ScriptObject The tricky part is that ScriptObjects are part of the user interface, so you can only access the Dispatcher property from the UI thread. At first this seems like a chicken-and-egg situation: you need a Dispatcher to get to the UI thread, but you need to be in the UI thread to get a Dispatcher.
This dilemma can be resolved by accessing a Dispatcher in your App.xaml.cs file and stashing it away in a static variable on application startup:
private void Application_Startup(object sender, StartupEventArgs e) {
...
UIThread.Dispatcher = RootVisual.Dispatcher;
}
UIThread is a simple static class:
public static class UIThread {
public static Dispatcher Dispatcher {get; set;}
public static void Run(Action a) {
Dispatcher.BeginInvoke(a);
}
}
At some point in the future, you can transfer execution to the UIThread by scheduling a function to run in it.
public class ProcessHttpResponse(...) {
...
UIThread.Run(UpdateUserInterface);
}
The parameter of Run is an Action delegate, which is a function that returns void and takes no parameters. That’s fine and good, but what if you want to pass some parameters to the function that updates the UI. The usual three choices for passing state in asynchronous applications apply, but it’s particularly easy and fun to use a closure here:
public class ProcessHttpResponse(...) {
...
var elementToUpdate=...;
var updateWithValue=...;
UIThread.Run(delegate() {
UpdateUserInterface(elementToUpdate,updateWithValue)
});
}
When to return?
If your application is complex, and you have nested asynchronous calls, you’re left with an interesting question: where is the best place to switch execution to the UI thread? You can switch to the UI Thread as soon as you get back from an HttpRequest or a WCF call and you must switch to the UI Thread before you access any methods or properties of the user interface. What’s best?
It is simple and safe to switch to the UI Thread immediately after requests return from the server. If you’re consistent in doing this, you’ll never have trouble accessing the UI thread, and you’ll never have trouble with race conditions between returning communication responses. On the other hand, you’ll lose the benefit of processing responses concurrently, which can improve speed and responsiveness on today’s multi-core computers.
It’s straightforward to exploit concurrency when a requests can be processed independently. For instance, imagine a VRML viewer written in Silverlight. Displaying a VRML would require the parsing of a file, the construction of the scene graph and the initialization of a 3-d engine, which may require building data structures such as a BSP Tree. Doing all of this work in the UI Thread would make the application lock up while a model is loading — it would be straightforward, instead, to construct all of the data structures required by the 3-d engine, and attach the fully initialized 3-d engine to the user interface as the last step. Since the data structures would be independent of the rest of the application, thread safety and liveness is a nonissue.
Matters can get more complicated, however, if the processing of a request requires access to application-wide data; response handlers running in multiple threads will probably corrupt shared data structures unless careful attention is paid to thread safety. One simple approach is to always access shared data from the UI Thread, and to transfer control to the UI Thread with UIThread.Run before accessing shared variables.
Conclusion
Silverlight 2 Beta 2 introduces a major change in the concurrency model for asynchronous communication requests. Unlike SL2B1, where asynchronous requests executed on the user interface thread, SL2B2 launches asynchronous callbacks on multiple threads. Although this model offers better performance and responsiveness, it requires Silverlight programmers to explicitly transfer execution to the UI thread before accessing UI objects: most SL2B1 applications will need to be reworked.
This article introduces a simple static class, UIThread, which makes it easy to schedule execution in the UI Thread.
Paul Houle on June 25th 2008 in Asynchronous Communications, Dot Net, Silverlight
![[Generation Five]](/q/wp-content/themes/mach-go/images/GenerationFive.png)
![[Reliable And Maintainable Software For The Next Generation]](/q/wp-content/themes/mach-go/images/ReliableAndMaintainableSoftwareForTheNextGeneration.png)

Jack Bond responded on 25 Jun 2008 at 7:57 pm #
There’s no chicken and egg, it’s perfectly safe to access a UIElement’s Dispatcher object from any thread. There would be little point in having it be a public property otherwise. You can also call a UIElement’s CheckAccess method from any thread without encountering any UnauthorizedAccessExceptions.
admin responded on 26 Jun 2008 at 7:58 am #
Jack, I checked this and you’re right.
However, you might not have a reference to a UIElement handy at the place where you want to switch to the UI Thread — I still think it’s good to have a Dispatcher squirreled away in a static field somewhere, because most of the obvious ways to get at a ScriptObject or UIElement statically don’t seem to work off when you’re not in the UI Thread.
Personally, I like having ‘choke points’ in my apps that let me control concurrency on an app-wide basis. It took me less than half an hour for me to adjust to the changes between beta 2 and beta 1 because I only needed to change one method… It’s much better to have a standard method you call rather than to grasp for whatever random UIElement you can find in a situation.
Jack Bond responded on 26 Jun 2008 at 11:40 am #
You’ve already got one:
Application.Current.RootVisual.Dispatcher
I’m not sure what you mean by “get at a ScriptObject or UIElement statically don’t seem to work off when you’re not in the UI Thread.”
If you are attempting to update a UIElement, presumably you’ve got a reference to it, at which point you can call CheckAccess and BeginInvoke if required. If you are attempting to BeginInvoke some arbitrary code on the UI thread, then you’ve got the static reference I listed above.
admin responded on 26 Jun 2008 at 12:50 pm #
Jack, Application.Current.RootVisual.Dispatcher doesn’t work. I get “Unauthorized Cross Thread Exception.”
There are a number of good reasons why asynchronous communications should be decoupled from the user interface thread. Here are two of them:
(1) As asynchrononous RIAs increase in complexity, they eventually need a notification infrastructure for data changes. The issue that there might be N user interface elements that are affected when a piece of data changes. Trying to hardwire all of these updates will drive you nuts. (I’ve tried it.) It’s better for UI elements to register their interest in certain data items and then let the notifier take over. The notifier will probably flip to the UI thread and then enumerate over all the subscribers: not flip over for each individual subscriber, or expect each subscriber to flip the thread itself.
(2) Code reuse. In a lot of cases we end up developing multiple apps and product lines, even when it’s just a few different test apps that are used in house. Often we write chunks of functionality that get used in multiple apps: it’s usually better to put “the tough stuff” like concurrency control into the reusable parts (which don’t know how they’ll be reused) rather than re-write them in the code that does the reusing.
Generation 5 » How Asynchronous Execution Works in RIAs responded on 26 Jun 2008 at 6:41 pm #
[...] components must be done from the user interface thread. (Fortunately, it’s easy to get back to the UI thread.) Subscribe to our RSS Feed to keep informed of breaking developments in Silverlight [...]
Joel Neubeck responded on 03 Jul 2008 at 1:10 pm #
Great blog post on what is happening in SLBeta 2.
One thing to note…you can just use Dispatcher.BeginInvoke(MyMethod). There is no need to take it from “Application.Current.RootVisual.Dispatcher” or store a second reference statically.
-Joel
http://joel.neubeck.net/
admin responded on 08 Jul 2008 at 8:04 am #
@Joel, I’m having trouble confirming your solution.
Maybe I’m doing something wrong, but if I try your example, Visual Studio says “Cannot access non-static method ‘BeginInvoke’ in static context;” I also fail to see any static members for System.Windows.Threading.Dispatcher in the Silverlight API reference.
Am I missing something?