Dispatcher and Multi-threading in Silverlight 3
June 27, 2009 7 Comments
In Silverlight 3, as with WinForms and WPF, we need to be careful about cross thread communication. Controls instantiated in the XAML DOM belong to the UI thread and only the UI thread can update them. To see this, try updating the UI from a different thread,
public MainPage() {
InitializeComponent();
// Explicitly start a new thread, Thread myThread = new Thread(FillRectangle); myThread.Start(); }
void FillRectangle() {
// Try to update the UI thread... MyRectangle.Fill = new SolidColorBrush(Colors.Red); }
You’ll see an error like this,
To alleviate this Silverlight gives us two constructs,
1. The Dispatcher class: This class guarantees that the code will be executed on the UI thread.
public MainPage() {
InitializeComponent();
// Explicitly start a new thread Thread myThread = new Thread(FillRectangle); myThread.Start(); }
void FillRectangle() {
// Can't update the UI thread directly //MyRectangle.Fill = new SolidColorBrush(Colors.Red); // But perfectly safe to update the UI using the Dispatcher Dispatcher.BeginInvoke(() => MyRectangle.Fill = new SolidColorBrush(Colors.Red)); }
2. The BackgroundWorker class: Using this class gives you a new thread but also gives you a way to update the UI in a safe way.
public MainPage() {
InitializeComponent();
BackgroundWorker bg = new BackgroundWorker(); // This method is called on the background thread bg.DoWork += CrossThreadUnsafe; // This method is called on the UI thread bg.RunWorkerCompleted += CrossThreadSafe; // Start the thread bg.RunWorkerAsync(); }
void CrossThreadUnsafe(object sender, DoWorkEventArgs e) { // Don't update the UI here - uncommenting will cause 'Invalid cross-thread access error' //MyRectangle.Fill = new SolidColorBrush(Colors.Red); }
void CrossThreadSafe(object sender, RunWorkerCompletedEventArgs e) {
// Perfectly safe to update the UI from here MyRectangle.Fill = new SolidColorBrush(Colors.Red); }
Or if you want, write your own BackgroundWorker class.
Also, Silverlight provides a DispatcherTimer class which is a UI-thread safe timer (as opposed to the Timer class), for an example see here.