UI Thread, Dispatchers, Background Workers & Async Network Programming
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.
TestServiceClient client = new TestServiceClient();
client.DoSomethingSlowCompleted+= (s, ea) =>{
// do something with the results here
Debug.WriteLine(ea.Result);
};
client.DoSomethingSlowAsync();
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.
private BackgroundWorker _worker = new BackgroundWorker();
private void RunLongProcess() {
_worker.WorkerReportsProgress = true;
ProgressBar.Minimum = 0;
ProgressBar.Maximum = 100;
// runs in Background Thread
_worker.DoWork += (s, e) =>
{
for (int i = 0; i < 100; i++)
{
// simulate long-running work
System.Threading.Thread.Sleep(500);
((BackgroundWorker)s).ReportProgress(i+1);
}
};
// runs in UI Thread
_worker.ProgressChanged += (s, e) => {
// this is on the UI thread, so you can update UI from here.
ProgressBar.Value = e.ProgressPercentage;
};
// runs in UI Thread
_worker.RunWorkerCompleted += (s, e) => {
// clean up after your stuff, yes, you can touch UI here.
};
_worker.RunWorkerAsync();
}
Of course, knowi