Tải bản đầy đủ (.pdf) (50 trang)

Netframwork 2.0 (phần 13) pot

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (457.21 KB, 50 trang )

Lesson 2: Using User Assistance Controls and Components 575
Table 12-6 Important Methods of the HelpProvider Component
Method Description
SetHelpKeyword Sets the keyword for a control, such as an index keyword or
a topic keyword. This keyword will be passed to the help file
when help is shown. The HelpNavigator setting determines
how the keyword is used.
SetHelpNavigator Sets the HelpNavigator for a control. This property deter-
mines how the help file is displayed.
SetHelpString Sets the help string for a control. If the HelpNamespace prop-
erty is not set to a file, the help string will be displayed in a
popup box over the control when the F1 button is pressed.
SetShowHelp Sets whether help is shown for a particular control.
Setting the HelpNavigator The SetHelpNavigator method allows you to determine
how help is displayed for a particular control. The SetHelpNavigator method requires
two parameters: a control that the HelpNavigator will be set for, and a member of the
HelpNavigator enumeration. The following example demonstrates how to set the Help-
Navigator for a Button control named Button1:
' VB
HelpProvider1.SetHelpNavigator(Button1, HelpNavigator.Find)
// C#
helpProvider1.SetHelpNavigator(Button1, HelpNavigator.Find);
Table 12-7 describes the members of the HelpNavigator enumeration.
Table 12-7 Members of the HelpNavigator Enumeration
Member Description
AssociateIndex The help file opens to the index entry for the first letter of the
specified keyword.
Find The help file opens to the search page.
Index The help file opens to the index.
576 Chapter 12 Enhancing Usability
Table 12-7 Members of the HelpNavigator Enumeration


Member Description
KeywordIndex The help file opens to the topic with the specified keyword if one
exists; otherwise, the index entry closest to the specified key-
word is displayed.
TableOfContents The help file opens to the table of contents.
Topic The help file opens to a specified topic if the topic exists.
TopicId The help file opens to a topic indicated by a numeric topic identifier.
Configuring Help for a Control The following example demonstrates how to use the
HelpProvider component to configure help for a control named Button1.
' VB
' This example assumes that a help file has been compiled for your
' application and the path to that file has been set in the HelpNamespace property.
' Sets help for Button1 to be shown.
HelpProvider1.SetShowHelp(Button1, True)
' Sets the help keyword for the control
HelpProvider1.SetHelpKeyword(Button1, "Button1")
' Sets the HelpNavigator for the control
HelpProvider1.SetHelpNavigator(Button1, HelpNavigator.KeywordIndex)
// C#
// This example assumes that a help file has been compiled for your
// application and the path to that file has been set in the HelpNamespace property.
// Sets help for Button1 to be shown.
helpProvider1.SetShowHelp(button1, true);
// Sets the help keyword for the control
helpProvider1.SetHelpKeyword(button1, "button1");
// Sets the HelpNavigator for the control
helpProvider1.SetHelpNavigator(button1, HelpNavigator.KeywordIndex);
Playing Sound Files and System Sounds
Sound files and system sounds can be used to communicate information or alerts to
your users. The SoundPlayer class in the System.Media namespace encapsulates all of

the functionality required to play sound files.
� To play a sound file with the SoundPlayer class
1. Create an instance of the SoundPlayer class that specifies the sound file to be
played, as shown here:
Lesson 2: Using User Assistance Controls and Components 577
' VB
Dim aPlayer As New System.Media.SoundPlayer("C:\mySoundFiles\Boom.wav")
// C#
System.Media.SoundPlayer aPlayer = new
System.Media.SoundPlayer(@"C:\mySoundFiles\Boom.wav");
2. Play the sound by calling the Play method, as shown:
' VB
aPlayer.Play
// C#
aPlayer.Play();
You can play system sounds by accessing the System.Media.SystemSounds class. This
class contains members that represent each of the system sounds, and they can be
played by calling the Play method.
� To play a system sound
Call the Play method of the appropriate system sound, as shown here:
' VB
System.Media.SystemSounds.Beep.Play()
// C#
System.Media.SystemSounds.Beep.Play();
Using the Timer Component to Raise an Event at Regular Intervals
The Timer component allows you raise the Timer.Tick event at regular intervals. By
writing code to handle this event, you can schedule your application to call methods
or take other actions at predefined intervals. For example, you might want to display
the current time in a Label control and update it every minute.
The key property of the Timer component is the Interval property. The Interval prop-

erty specifies the number of milliseconds between intervals of the Tick event. For
example, if the Interval property is set to 2000, the Tick event will be raised every two
seconds. The Interval property can be set in the Properties window or in code, as
shown in the following example:
' VB
Timer1.Interval = 2000
// C#
timer1.Interval = 2000;
578 Chapter 12 Enhancing Usability
Another important property of the Timer component is the Enabled property. If the
Enabled property is set to False, the Timer.Tick event will not be raised. When the
Enabled property is set to True, the Timer.Tick event will be raised at a frequency deter-
mined by the Interval property.
The Timer.Start and Timer.Stop methods allow you to start and stop the Timer, respec-
tively. These methods are simply shorthand ways of setting the Enabled property. Call-
ing the Timer.Start method sets the Timer.Enabled property to True and commences
regular firing of the Tick event. Calling the Timer.Stop method sets the Timer.Enabled
property to False and ceases firing of the Tick event.
The following example demonstrates a handler for the Timer.Tick event. This sample
code updates the text in Label1 with the current time every time the Tick event is raised.
' VB
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles Timer1.Tick
Label1.Text = Now.ToLongTimeString
End Sub
// C#
private void timer1_Tick(object sender, EventArgs e)
{
label1.Text = DateTime.Now.ToLongTimeString;
}

Using the HScrollBar and VScrollBar Controls
The HScrollBar and VScrollBar controls are controls that are designed to provide easy
navigation through a long list of items or values by scrolling within an application or
control. The HScrollBar control represents a horizontal scroll bar and the VScrollBar
control represents a vertical scroll bar, but the two controls function identically other-
wise. The ScrollBar controls consist of two scrollbar buttons at either end of the con-
trol, a slider, and a slider track in which the slider can move. The user can position the
slider and thereby change the Value property.
The ScrollBar controls are distinct from the scrollbars that appear in Forms or scrollable
controls—those scroll bars are integral parts of the control or form that they function
with. The ScrollBar controls are designed for independent operation or operation with
controls that do not normally have scrollbars, such as the PictureBox control. The
important properties of the ScrollBar controls are shown in Table 12-8.
Lesson 2: Using User Assistance Controls and Components 579
Table 12-8 Important Properties of the Scrollbar Controls
Property Description
LargeChange The amount the Value property changes when the user presses the
PageUp or PageDown keys or clicks in the ScrollBar track.
Maximum The maximum value for the scrollbar. In HScrollBar, the Value
property is equal to the Maximum property when the scrollbar
slider is all the way to the right in the scroll track. In VScrollBar, the
Value property is equal to the Maximum property when the scroll-
bar slider is all the way at the bottom of the scroll track.
Minimum The minimum value for the scrollbar. In HScrollBar, the Value prop-
erty is equal to the Minimum property when the scrollbar slider is
all the way to the left in the scroll track. In VScrollBar, the Value
property is equal to the Minimum property when the scrollbar
slider is all the way at the top of the scroll track.
SmallChange The amount the Value property changes when the user presses one
of the arrow keys or clicks a scrollbar button.

Value The current value of the Scrollbar control. This property reflects
the current location of the scrollbar slider.
Persisting Application Settings Between Sessions
The .NET Framework allows you to persist property values between user sessions in
the form application settings and access and change those settings at run time. You
might, for example, create settings that determine the color scheme of your applica-
tion or settings that “remember” user names or data connection strings.
Persisting settings is a two-step process. First, you create a setting and give it a unique
name and a value. The value can be any object and should be appropriate for the prop-
erty that you want to persist. Second, the property that you want to persist is bound
to the setting. At run time, the settings can be accessed, changed, and saved if need be.
Creating Settings at Design Time Visual Studio 2005 provides user interface tools that
allow you to create settings quickly and easily. You can use the Settings editor (shown in
Figure 12-2) to create and edit new settings.
580 Chapter 12 Enhancing Usability
Figure 12-2 The Settings editor for creating and editing new settings
The Settings editor has four properties that must be set when they are created. The
Name must be unique in the application. The Type property represents the type of set-
ting, which should be appropriate for the property you want to bind it to. The Scope
property must be set to either Application or User. Settings that are scoped for the
application are read-only at run time and cannot be changed by the user. Settings that
are scoped for the user are read-write at run time and can be changed and saved by the
user. Finally, a value must be provided for the setting. This value must be of the type
indicated by the Type property.
� To create a setting at design time
1. In Solution Explorer, right-click the project and choose Properties.
2. In the main window, select the Settings tab.
3. Set the Name, Type, Scope, and Value for the new setting.
4. If your application has not yet been saved, choose Save All from the File menu to
save your application.

Once a setting has been created, you can bind it to a property in the Properties window.
� To bind a setting to a property at design time
1. In the Properties window for a control, expand (ApplicationSettings) and then click
the button next to (PropertyBinding) to open the Application Settings window.
2. Locate the property that you want to bind to a setting. Select the appropriate set-
ting from the drop-down box to the right of the property name. If no appropriate
setting exists, you can create a new setting by clicking the (New…) link in the bot-
tom of the drop-down box.
Lesson 2: Using User Assistance Controls and Components 581
Accessing Settings at Run Time You can read the values of your settings at run time
and change and save the values of user-scoped settings. In Visual Basic, settings are
exposed via the My object, and changes made to any user-scoped settings values are
automatically saved. In C#, you can access settings through the Properties.Set-
tings.Default object, but any changes made must be saved manually. At design time,
individual settings appear in Intellisense as properties of the Settings object and can be
treated in code as such. The following example demonstrates how to change the
value of a user-scoped string setting named TitleSetting:
' VB
My.Settings.TitleSetting = "This is the new title"
// C#
Properties.Settings.DefaultSettings.TitleSetting = "This is the new Title";
Properties.Settings.DefaultSettings.Save();
Quick Check
1. What is the purpose of the Timer component?
2. What is the purpose of the ErrorProvider component?
Quick Check Answers
1. The Timer component is used to execute code at regular intervals.
2. The error provider is used to provide a visual cue to users when a validation
error occurs.
Lab: Practice with User Assistance Controls

In this lab, you will create a small application that uses a timer to display and update
the current time in a label, and you will use the functionality and many of the controls
that have been discussed in this lesson. Although the end result of the lesson is some-
what contrived, it will allow you to practice with the different aspects of this lesson.
� Exercise 1: Creating a Simple Digital Clock
1. In Visual Studio, create a new Windows Forms application.
2. From the Toolbox, drag a Label control and a Timer component onto the form.
3. Select the Timer component. In the Properties window, set the Interval property
to 1000 and the Enabled property to True.
4. In the Designer, double-click the Timer component to open the default event
handler for the Timer1.Tick event. Add the following code to this method:
582 Chapter 12 Enhancing Usability
' VB
Label1.Text = Now.ToLongTimeString
// C#
label1.Text = System.DateTime.Now.ToLongTimeString();
5. Press F5 to compile and run your application. Note that the current time is
updated in the Label control every second.
� Exercise 2: Using the PropertyGrid
1. From the Toolbox, drag a PropertyGrid control onto the form that you created in
the last exercise.
2. In the Properties window, set the Dock property of the PropertyGrid control to
Right.
3. In the Properties window, set the SelectedObject property of the PropertyGrid con-
trol to Timer1.
4. Press F5 to compile and run the application. You can now set the properties of
the Timer at run time via the PropertyGrid control.
� Exercise 3: Providing Tooltips for Your Application
1. From the Toolbox, drag a ToolTip component onto the form you created in Exer-
cise 1, “Creating a Simple Digital Clock.”

2. Select Label1. In the Properties window, set the tooltip on ToolTip1.
3. Press F5 to compile and run your application. Note that your label now has a
tooltip associated with it.
� Exercise 4: Using Settings
1. In Solution Explorer, for the application you started in Exercise 1, right-click the
project and choose Properties.
2. In the Properties pane, choose the Settings tab.
3. In the Settings window, create a setting with the following properties:
Property Value
Name IntervalSetting
Type Integer
Scope User
Value 1000
Lesson 2: Using User Assistance Controls and Components 583
4. In the Designer, select Timer1. In the Properties window, expand (Application
Settings) and then click the button next to (PropertyBinding) to open the Appli-
cation Settings window.
5. In the Application Settings window, bind the Interval property to the IntervalSetting
setting.
6. In the Designer, select the Form. In the Properties window, click the events but-
ton to list the events for the form. Double-click the cell next to the FormClosing
event to open the default event handler for the Form1.FormClosing event. Add the
following code to this event handler:
' VB
My.Settings.IntervalSetting = Timer1.Interval
// C#
Properties.Settings.Default.IntervalSetting = timer1.Interval;
Properties.Settings.Default.Save();
7. From the File menu, choose Save All.
8. Press F5 to compile and run your application. Any changes that you make to the

interval property will be persisted between sessions.
Lesson Summary
■ The PropertyGrid control allows you to set properties for controls in your appli-
cation through a grid-style user interface. The SelectedObject property indicates
the object for which the properties can be set.
■ The ProgressBar control allows you to inform the user about progress for time-
consuming processes such as file downloads. The Minimum and Maximum prop-
erties represent the minimum and maximum values for the ProgressBar, and the
Value control represents the current value.
■ The StatusStrip control is a ToolStrip control that is designed to display information
about the status of the application. ToolStripStatusLabel and ToolStripProgressBar
are ToolStripItem controls that are designed to work with the StatusStrip.
■ The ToolTip component allows you to display tooltips for the controls on your
form.
■ The ErrorProvider component allows you to display errors in user input in your
application. You can validate user input by adding code to the Validating event
handler. If the user input is not valid, use the SetError method of the error pro-
vider to set the error.
584 Chapter 12 Enhancing Usability
■ The HelpProvider component enables you to integrate HTML Help 1.x files (.chm
and .htm) with your application. The HelpNamespace property represents the
location of the help file that is associated with the HelpProvider component. You
can call SetShowHelp to set F1 help for a control and SetHelpKeyword to set the
keyword that will be passed on to the help file.
■ The SoundPlayer component allows you to play sound files. You can use the System-
Sounds class to play system sounds at run time.
■ The Timer component allows you to execute actions at regular intervals. You can
handle the Timer.Tick event to define code that is executed at regular intervals.
The Interval property determines how frequently the Timer.Tick event is raised.
■ The HScrollBar and VScrollBar controls are designed to provide a user interface

that allows rapid access to a large range of values or a long list of options. The
Minimum and Maximum properties represent the minimum and maximum val-
ues for the control; the Value property represents the current value and is tied to
the current position of the slider.
■ Application settings allow you to persist settings between application settings.
Application-scoped settings are read-only and user-scoped settings are read-
write at run time. You can access settings via the My.Settings object in Visual
Basic or the Properties.Settings.Default object in C#.
Lesson Review
The following questions are intended to reinforce key information presented in this
lesson. The questions are also available on the companion CD if you prefer to review
them in electronic form.
NOTE Answers
Answers to these questions and explanations of why each choice is right or wrong are located in
the “Answers” section at the end of the book.
1. Which of the following code examples will advance the value of a progress bar
named ProgressBar1 by 10? (Choose all that apply.)
A.
' VB
ProgressBar1.Step = 10
ProgressBar1.PerformStep
// C#
progressBar1.Step = 10;
progressBar1.PerformStep();
Lesson 2: Using User Assistance Controls and Components 585
B. ' VB
ProgressBar1.Step = 10
// C#
progressBar1.Step = 10;
C. ' VB

ProgressBar1.Increment(10)
// C#
progressBar1.Increment(10);
D. ' VB
ProgressBar1.Step = 10
ProgressBar1.Increment
// C#
progressBar1.Step = 10;
progressBar1.Increment();
2. Given a TextBox control, an ErrorProvider component, and a validation routine in
the Validating event handler for that text box, which of the following is required
to complete the validation routine and display an error icon when the user input
is not valid? (Choose all that apply.)
A. Set the CausesValidation property for other controls on the form to True.
B. Call the ErrorProvider.SetError method and set the error to an informative
string when user input is not valid.
C. Call the ErrorProvider.SetError method and set the error to an empty value
when user input is valid.
D. Call the ErrorProvider.Validate method to validate the text box input.
3. Given a TextBox control named TextBox1 and a HelpProvider control named
HelpProvider1 with the HelpNamespace property set to an appropriate help file,
which of the following code samples will cause the search page for help to be dis-
played when the F1 key is pressed and TextBox1 has the focus?
A.
' VB
HelpProvider1.SetShowHelp(TextBox1, True)
// C#
helpProvider1.SetShowHelp(textBox1, true);
B. ' VB
HelpProvider1.SetShowHelp(TextBox1, True)

HelpProvider1.SetHelpNavigator(TextBox1, HelpNavigator.Find)
// C#
helpProvider1.SetShowHelp(textBox1, true);
helpProvider1.SetHelpNavigator(textBox1, HelpNavigator.Find);
586 Chapter 12
C.
D.
Enhancing Usability
' VB
HelpProvider1.SetShowHelp(TextBox1, True)
HelpProvider1.SetHelpNavigator(TextBox1, HelpNavigator.Topic)
// C#
helpProvider1.SetShowHelp(textBox1, true);
helpProvider1.SetHelpNavigator(textBox1, HelpNavigator.Topic);
' VB
HelpProvider1.SetShowHelp(TextBox1, True)
HelpProvider1.SetHelpString(TextBox1, “Search”)
// C#
helpProvider1.SetShowHelp(textBox1, true);
helpProvider1.SetHelpString(textBox1, “Search”);
Chapter 12 Review 587
Chapter Review
To further practice and reinforce the skills you learned in this chapter, you can per-
form the following tasks:
■ Review the chapter summary.
■ Review the list of key terms introduced in this chapter.
■ Complete the case scenarios. These scenarios set up real-world situations involv-
ing the topics of this chapter and ask you to create a solution.
■ Complete the suggested practices.
■ Take a practice test.

Chapter Summary
■ Applications should be designed to support the principles of accessibility. Appli-
cations should support the standard system settings, they should be designed to
have a variety of inputs, and they should convey no information solely by sound.
Each control exposes several accessibility properties that are used by accessibil-
ity aids to gather and display information.
■ The PropertyGrid control allows you to set properties for controls in your appli-
cation through a grid-style user interface. The ProgressBar control allows you to
inform the user about progress for time-consuming processes. The StatusStrip
control is a ToolStrip control that is designed to display information about the
status of the application.
■ The ToolTip, ErrorProvider, and HelpProvider components provide additional
design-time properties for controls on the form. The ToolTip component allows you
to display tooltips for the controls on your form. The ErrorProvider component
allows you to display errors in user input in your application. The HelpProvider
component enables you to integrate HTML Help 1.x files with your application.
■ The SoundPlayer component allows you to play sound files. The Timer compo-
nent allows you to execute actions at regular intervals. The HScrollBar and
VScrollBar controls are designed to provide a user interface that allows rapid
access to a large range of values or a long list of options.
■ Application settings allow you to persist settings between application settings.
You can access settings via the My.Settings object in Visual Basic or the Properties
.Settings.Default object in C#.
588 Chapter 12 Review
Key Terms
■ accessible design
■ application scope
■ setting
■ user scope
Case Scenarios

In the following case scenarios, you will apply what you’ve learned about enhancing
usability. You can find answers to these questions in the “Answers” section at the end
of this book.
Case Scenario 1: Putting the Final Touches on the Document
Management System
Your company has created a document management application for Fabrikam, Inc.,
and you are in charge of putting the final touches on it. This application allows the
user to browse documents from a very long list of documents stored on a central
server, download and view those documents, and make any necessary changes. Most
of the functionality is complete. You have been tasked with making the user interface
friendlier. The following are your key requirements.
Key Requirements
■ The application should provide a way to navigate the list of documents quickly
and easily in the user interface.
■ The application should provide feedback for the download status and provide a
cue to the user when the download is complete.
■ Help should be readily available to the user, and input values should be vali-
dated and provide immediate feedback if they are not valid.
Questions
What strategies can you use to implement the key requirements?
Chapter 12 Review 589
Case Scenario 2: Making the Document Management Application
Accessible
The document management application is almost complete. You are now in charge of
making the application accessible for all users. You have the following specific
requirements:
■ Application must support high-contrast mode.
■ Application must be accessible to hearing-impaired users.
■ Application must be accessible to users who are unable to use a mouse.
■ Application must work well with all standard usability aids.

Questions
What strategies can you use to implement these requirements in this application?
Suggested Practices
■ Create an application that allows you to browse sound files on your computer
and play them with the SoundPlayer component.
■ Extend the application created in the lab in Lesson 2, “Practice with User Assis-
tance Controls,” to include F1 help and validation for property values.
Take a Practice Test
The practice tests on this book’s companion CD offer many options. For example, you
can test yourself on just the content covered in this chapter, or you can test yourself on
all the 70-526 certification exam content. You can set up the test so that it closely sim-
ulates the experience of taking a certification exam, or you can set it up in study mode
so that you can look at the correct answers and explanations after you answer each
question.
MORE INFO Practice tests
For details about all the practice test options available, see “How to Use the Practice Tests” in this
book’s Introduction.

Chapter 13
Asynchronous Programming
Techniques
Frequently, you will have to create applications that perform time-consuming opera-
tions such as file downloads or complex calculations. These operations can cause the
user interface to lock up and become unresponsive, thus leading to an unpleasant
user experience. By using asynchronous programming techniques, you can enable
time-consuming operations to be run asynchronously, thus keeping the user interface
responsive while the operations are run.
Exam objectives in this chapter:
■ Run a background process by using the BackgroundWorker component.
■ Announce the completion of a background process by using the Background-

Worker component.
■ Cancel a background process by using the BackgroundWorker component.
■ Report the progress of a background process by using the BackgroundWorker
component.
■ Request the status of a background process by using the BackgroundWorker
component.
■ Implement advanced asynchronous techniques.
■ Create an asynchronous method.
■ Create a new process thread.
Lessons in this chapter:
■ Lesson 1: Managing a Background Process with the
BackgroundWorker Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 593
■ Lesson 2: Implementing Asynchronous Methods . . . . . . . . . . . . . . . . . . . . . . 605
591
592 Chapter 13 Asynchronous Programming Techniques
Before You Begin
To complete the lessons in this chapter, you must have:
■ A computer that meets or exceeds the minimum hardware requirements listed in
the “Introduction” at the beginning of the book.
■ Visual Studio 2005 Professional Edition installed on your computer.
■ An understanding of Visual Basic or C# syntax and familiarity with the .NET
Framework.
Real World
Matt Stoecker
Even with ever increasing processor speeds, time-consuming tasks are still a cen-
tral part of many of the applications I write. Before Visual Studio 2005, creating
asynchronous operations was difficult and time-consuming. With the introduc-
tion of the BackgroundWorker component, creating simple asynchronous opera-
tions is easily accessible to programmers of all levels. For more advanced
operations, delegates and threads provide the level of functionality needed.

Lesson 1: Managing a Background Process with the BackgroundWorker Component 593
Lesson 1: Managing a Background Process with the
BackgroundWork er Component
Frequently you are required to perform tasks that consume fairly large amounts of
time, such as file downloads. The BackgroundWorker component provides an easy way
to run time-consuming processes in the background, thereby leaving the user inter-
face responsive and available for user input.
After this lesson, you will be able to:
■ Run a background process by using the BackgroundWorker component.
■ Announce the completion of a background process by using the BackgroundWorker
component.
■ Cancel a background process by using the BackgroundWorker component.
■ Report the progress of a background process by using the BackgroundWorker
component.
■ Request the status of a background process by using the BackgroundWorker
component.
Estimated lesson time: 45 minutes
The BackgroundWorker component is designed to allow you to execute time-consuming
operations on a separate, dedicated thread. This allows you to run operations that
take extended periods of time, such as file downloads and database transactions,
asynchronously and allow the user interface to remain responsive.
The key method of the BackgroundWorker component is the RunWorkerAsync method.
When this method is called, the BackgroundWorker component raises the DoWork
event. The code in the DoWork event handler is executed on a separate, dedicated
thread, allowing the user interface to remain responsive. Important members of the
BackgroundWorker component are shown in Table 13-1.
Table 13-1 Important Members of the BackgroundWorker Component
Member Description
CancellationPending Property. Indicates whether the application has
requested cancellation of a background operation.

IsBusy Property. Indicates whether the BackgroundWorker
is currently running an asynchronous operation.
594 Chapter 13 Asynchronous Programming Techniques
Table 13-1 Important Members of the BackgroundWorker Component
Member Description
WorkerReportsProgress Property. Indicates whether the BackgroundWorker
component can report progress updates.
WorkerSupportsCancellation Property. Indicates whether the BackgroundWorker
component supports asynchronous cancellation.
CancelAsync Method. Requests cancellation of a pending back-
ground operation.
ReportProgress Method. Raises the ProgressChanged event.
RunWorkerAsync Method. Starts the execution of a background oper-
ation by raising the DoWork event.
DoWork Event. Occurs when the RunWorkerAsync method is
called. Code in the DoWork event handler is run on
a separate and dedicated thread.
ProgressChanged Event. Occurs when ReportProgress is called.
RunWorkerCompleted Occurs when the background operation has been
completed, cancelled, or has raised an exception.
Running a Background Process
The RunWorkerAsync method of the BackgroundWorker component starts the execu-
tion of the background process by raising the DoWork event. The code in the DoWork
event handler is executed on a separate thread. The following procedure explains how
to create a background process.
� To create a background process with the BackgroundWorker component
1. From the Toolbox, drag a BackgroundWorker component onto the form.
2. In the component tray, double-click the BackgroundWorker component to create
the default event handler for the DoWork event. Add the code that you want to
run on the separate thread. An example is shown below.

' VB
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal _
e As System.ComponentModel.DoWorkEventArgs) Handles _
BackgroundWorker1.DoWork
' Insert time-consuming operation here
Lesson 1: Managing a Background Process with the BackgroundWorker Component 595
End Sub
// C#
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// Insert time-consuming operation here
}
3. Elsewhere in your code, start the time-consuming operation on a separate thread
by calling the RunWorkerAsync method, as shown:
' VB
BackgroundWorker1.RunWorkerAsync()
// C#
backgroundWorker1.RunWorkerAsync();
Providing Parameters to the Background Process
Sometimes you will want to run a background process that requires a parameter.
For example, you might want to provide the address of a file for download. You can
provide a parameter in the RunWorkerAsync method. This parameter will be avail-
able as the Argument property of the instance of DoWorkEventArgs in the DoWork
event handler.
� To provide a parameter to a background process
1. Include the parameter in the RunWorkerAsync call, as shown below:
' VB
RunWorkerAsync("C:\myfile.txt")
// C#
RunWorkerAsync("C:\\myfile.txt");

2. Retrieve the parameter from the DoWorkEventArgs.Argument property and cast it
appropriately to use it in the background process. An example is shown below:
' VB
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal _
e As System.ComponentModel.DoWorkEventArgs) Handles _
BackgroundWorker1.DoWork
Dim myPath As String
myPath = CType(e.Argument, String)
‘ Use the argument in the process
RunTimeConsumingProcess(myString)
End Sub
// C#
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
596 Chapter 13 Asynchronous Programming Techniques
string myPath;
myPath = (string)e.Argument;
// Use the argument in the process
RunTimeConsumingProcess(myString);
}
Announcing the Completion of a Background Process
When the background process terminates, whether because the process is completed
or cancelled, the RunWorkerCompleted event is raised. You can alert the user to the
completion of a background process by handling the RunWorkerCompleted event. An
example is shown below:
' VB
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As _
System.Object, ByVal e As _
System.ComponentModel.RunWorkerCompletedEventArgs) Handles _
BackgroundWorker1.RunWorkerCompleted

MsgBox("Background process completed!")
End Sub
// C#
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs
e)
{
System.Windows.Forms.MessageBox.Show("Background process completed");
}
You can ascertain if the background process was cancelled by reading the e.Cancelled
property, as shown below:
' VB
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As _
System.Object, ByVal e As _
System.ComponentModel.RunWorkerCompletedEventArgs) Handles _
BackgroundWorker1.RunWorkerCompleted
If e.Cancelled Then
MsgBox("Process was cancelled!")
Else
MsgBox("Process completed")
End If
End Sub
// C#
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs
e)
{
if (e.Cancelled)
{
Lesson 1: Managing a Background Process with the BackgroundWorker Component 597
System.Windows.Forms.MessageBox.Show ("Process was cancelled!");
}

else
{
System.Windows.Forms.MessageBox.Show("Process completed");
}
}
Returning a Value from a Background Process You might want to return a value from
a background process. For example, if your process is a complex calculation you
would want to return the end result. You can return a value by setting the Result prop-
erty of the DoWorkEventArgs in the DoWorkEventHandler. This value will then be avail-
able in the RunWorkerCompleted event handler as the Result property of the
RunWorkerCompletedEventArgs parameter, as shown in the following example:
' VB
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal _
e As System.ComponentModel.DoWorkEventArgs) Handles _
BackgroundWorker1.DoWork
' Assigns the return value of a method named ComplexCalculation to
' e.Result
e.Result = ComplexCalculation
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As _
System.Object, ByVal e As _
System.ComponentModel.RunWorkerCompletedEventArgs) Handles _
BackgroundWorker1.RunWorkerCompleted
MsgBox("The result is " & e.Result.ToString)
End Sub
// C#
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// Assigns the return value of a method named ComplexCalculation to
// e.Result

e.Result = ComplexCalculation();
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
System.Windows.Forms.MessageBox.Show("The result is " +
e.Result.ToString());
}
Cancelling a Background Process
You might want to implement the ability to cancel a background process. Back-
groundWorker supports the ability to cancel a background process, but you must
implement must of the cancellation code yourself. The WorkerSupportsCancellation
property of the BackgroundWorker component indicates whether the component
598 Chapter 13 Asynchronous Programming Techniques
supports cancellation. You can call the CancelAsync method to attempt to cancel the
operation; doing so sets the CancellationPending property of the BackgroundWorker
component to True. By polling the CancellationPending property of the Background-
Worker component, you can determine whether or not to cancel the operation.
� To implement cancellation for a background process
1. In the Properties window, set the WorkerSupportsCancellation property to True to
enable the BackgroundWorker component to support cancellation.
2. Create a method that is called to cancel the background operation. The following
example demonstrates how to cancel a background operation in a Button.Click
event handler.
' VB
Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles btnCancel.Click
BackgroundWorker1.CancelAsync()
End Sub
// C#
private void btnCancel_Click(object sender, EventArgs e)

{
BackgroundWorker1.CancelAsync();
}
3. In the BackgroundWorker.DoWork event handler, poll the BackgroundWorker.Can-
cellationPending property, and implement code to cancel the operation if it is
True. You should also set the e.Cancel property to True as shown in the following
example:
' VB
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal _
e As System.ComponentModel.DoWorkEventArgs) Handles _
BackgroundWorker1.DoWork
For i As Integer = 1 to 1000000
TimeConsumingMethod()
If BackgroundWorker1.CancellationPending Then
e.Cancel = True
Exit Sub
End If
Next
End Sub
// C#
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < 1000000; i++)
{
TimeConsumingMethod();
if (backgroundworker1.CancellationPending)
Lesson 1: Managing a Background Process with the BackgroundWorker Component 599
{
e.Cancel = true;
return;

}
}
}
Reporting Progress of a Background Process with BackgroundWorker
For particularly time-consuming operations, you might want to report progress back
to the primary thread. You can report progress of the background process by calling
the ReportProgress method. This method raises the BackgroundWorker.ProgressChanged
event and allows you to pass a parameter that indicates the percentage of progress
that has been completed to the methods that handle that event. The following exam-
ple demonstrates how to call the ReportProgress method from within the Background-
Worker.DoWork event handler and then update a ProgressBar control in the
BackgroundWorker.ProgressChanged event handler.
' VB
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal _
e As System.ComponentModel.DoWorkEventArgs) Handles _
BackgroundWorker1.DoWork
For i As Integer = 1 to 10
TimeConsumingProcess()
' Calls the Report Progress method, indicating the percentage
' complete
BackgroundWorker1.ReportProgress(i*10)
Next
End Sub
Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As _
System.Object, ByVal e As _
System.ComponentModel.ProgressChangedEventArgs) Handles _
BackgroundWorker1.ProgressChanged
ProgressBar1.Value = e.ProgressPercentage
End Sub
// C#

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 1;i < 11; i++)
{
TimeConsumingProcess();
// Calls the Report Progress method, indicating the percentage
// complete
backgroundWorker1.ReportProgress(i*10);
}
}
private void backgroundWorker1_ProgressChanged(object sender,

×