Multithreaded User Interfaces


Because the Windows Forms Designer provides so much functionality via drag and drop and the Properties window, it might be a while before you get to the meat of your programming chores. When you do, though, you're bound to run into a task that takes long enough to annoy your users if you make them wait while it completesfor example, printing, searching, or calculating the last digit of pi.

It's especially annoying if your application freezes while an operation takes place on the UI thread, showing a blank square where the main form used to be and giving your users time to consider your competitors' applications. To build applications that remain responsive in the face of long-running operations, you need to create and manage worker threads from your main application (UI) thread, as well as ensure safe communication between the UI threads and worker threads. If the thought of doing this fills you with trepidation, then have no fear: Windows Forms encapsulates these complexities within a single component, BackgroundWorker, which you can drop onto a form and configure from the Windows Forms Designer.

For example, consider the application in Figure 1.29, which provides the potentially long-running ability to calculate pi to any number of decimal places.

Figure 1.29. Digits of Pi Calculator


To have the pi calculation execute on a worker thread, simply double-click the BackgroundWorker component. The Windows Forms Designer automatically creates an event handler for BackgroundWorker's default DoWork event:

// AsyncCalcPiForm.cs partial class AsyncCalcPiForm : Form {   ...   void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) {     // Pi calculation code     ...   }   ... }


The job of initiating the long-running operation and having the DoWork code execute is left up to you, although it is simply a case of invoking BackgroundWorker.DoWorkAsync:

// AsyncCalcPiForm.cs partial class AsyncCalcPiForm : Form {   ...   void calcButton_Click(object sender, EventArgs e) {     ...     // Initiate asynchronous worker thread     this.backgroundWorker.RunWorkerAsync(digits);   }   void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) {...}   ... }


When RunWorkAsync is invoked, BackgroundWorker creates a worker thread from the thread pool, transitions to it, and fires the DoWork event. All this is done behind the scenes and, as long as you follow the golden rule, is thread safe. If you need to update controls on the UI thread from a worker threadfor example, to report the progress of a long-running operationBackgroundWorker provides additional mechanisms for doing so safely, as well as for canceling a long-running operation mid-execution. These details and more are covered in Chapter 18: Multithreaded User Interfaces.




Windows Forms 2.0 Programming
Windows Forms 2.0 Programming (Microsoft .NET Development Series)
ISBN: 0321267966
EAN: 2147483647
Year: 2006
Pages: 216

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net