Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Daniel Solis - Illustrated C# 2010 - 2010.pdf
Скачиваний:
16
Добавлен:
11.06.2015
Размер:
11.23 Mб
Скачать

CHAPTER 22 INTRODUCTION TO ASYNCHRONOUS PROGRAMMING

The BackgroundWorker Class

Although much of asynchronous programming is complex, the BackgroundWorker class makes it simple to perform a task in the background on a separate thread. This class was designed primarily for GUI programming (Windows Forms and WPF) to allow them to offload time-consuming tasks from the main thread to a background thread. Figure 22-1 illustrates the key members of the class. The following is an overview of these members:

The first two properties shown in the figure are used to set whether the background task can report its progress to the main thread and whether it supports cancellation from the main thread. You use the third property to find out whether the background task is running.

The class has three events, which are used to signal different program events and states. You need to write event handlers for these events to take whatever actions are appropriate for your program.

The DoWork event is raised when the background thread starts.

The ProgressChanged event is raised when the background task reports progress.

The RunWorkerCompleted event is raised when the background worker exits.

The three methods are used to initiate actions or change state.

Calling the RunWorkerAsync method retrieves a background thread that executes the DoWork event handler.

Calling the CancelAsync method sets the CancellationPending property to true, potentially, although not necessarily, canceling the thread. It is the responsibility of the DoWork event handler to inspect this property to determine whether it should stop its processing.

The ReportProgress method can be called by the DoWork event handler (from the background thread) when it wants to report its progress to the main thread.

Figure 22-1. The key members of the BackgroundWorker class

602

CHAPTER 22 INTRODUCTION TO ASYNCHRONOUS PROGRAMMING

To use a BackgroundWorker class object, you need to write the following event handlers. The first is required since it contains the code you want to be executed by the background thread, but the other two are optional, depending on the needs of your program.

The handler attached to the DoWork event contains the code you want executed in the background on a separate thread.

In Figure 22-2, this handler is named DoTheWork and is in a gradient-shaded box to illustrate that it’s executed in the separate thread.

The DoWork event is raised when the main thread calls the RunWorkerAsync method.

The handler attached to the ProgressChanged event should contain the code to be executed on the main thread when the background task reports its progress.

The ProgressChanged event is raised when the background process calls the ReportProgress method.

Calling the ReportProgress method is how the background thread communicates with the main thread.

The handler attached to the RunWorkerCompleted event should contain the code to be executed on the main thread after the background thread completes the execution of the DoWork event handler.

Figure 22-2 shows the structure of your program, with the event handlers attached to the events of the BackgroundWorker object.

Figure 22-2. Your code supplies event handlers for the events that control the flow through execution of

the tasks.

603

CHAPTER 22 INTRODUCTION TO ASYNCHRONOUS PROGRAMMING

The delegates for these event handlers are the following. Each takes an object reference as the first parameter and a specialized subclass of the EventArgs class as the second parameter.

void DoWorkEventHandler

( object sender, DoWorkEventArgs e )

 

 

 

 

 

 

void

ProgressChangedEventHandler

(

object

sender,

ProgressChangedEventArgs e )

void

RunWorkerCompletedEventHandler (

object

sender,

RunWorkerCompletedEventArgs e)

Figure 22-3 illustrates the structure of the EventArg classes used by these event handlers.

Figure 22-3. The EventArg classes used by the BackgroundWorker event handlers

When you have the event handlers written and attached to their events, you can use the class by doing the following:

Start by creating an object of the BackgroundWorker class and configuring it.

If you want the worker thread to communicate progression to the main thread, then set the

WorkerReportsProgress property to true.

If you want to be able to cancel the worker thread from the main thread, then set the

WorkerSupportsCancellation property to true.

Now that the object is configured, you can start it by calling the object’s RunWorkerAsync method. This retrieves a background thread that raises the DoWork event and executes the event’s handler in the background.

604

CHAPTER 22 INTRODUCTION TO ASYNCHRONOUS PROGRAMMING

Now you have both the main thread and the background thread running. While the background thread is running, you can continue processing on the main thread.

In the main thread, if you’ve enabled the WorkerSupportsCancellation property, then you can call the object’s CancelAsync method. This does not cancel the background thread! Instead, it sets the object’s CancellationPending property to true that needs to be checked by the DoWork event handler code running on the background thread.

The background thread, in the meantime, continues to perform its computational tasks, as well as doing the following:

If the WorkerReportsProgress property is true and the background thread has progress to report to the main thread, then it must call the BackgroundWorker object’s ReportProgress method. When the background thread calls the ReportProgress method, this raises the ProgressChanged event in the main thread, which runs the corresponding event handler.

If the WorkerSupportsCancellation property is enabled, then the DoWork event handler code should regularly check the CancellationPending property to determine whether it has been canceled. If so, it should exit.

If the background thread finishes its processing without being canceled, it can return a result to the main thread by setting the Result field in the DoWorkEventArgs parameter shown previously, in Figure 22-3.

When the background thread exits, the RunWorkerCompleted event is raised, and its handler is executed on the main thread. The RunWorkerCompletedEventArgs parameter can contain information from the now completed background thread, such as the return value and whether the thread was canceled.

605

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]