BackgroundWorker Klas
Definitie
Belangrijk
Bepaalde informatie heeft betrekking op een voorlopige productversie die aanzienlijk kan worden gewijzigd voordat deze wordt uitgebracht. Microsoft biedt geen enkele expliciete of impliciete garanties met betrekking tot de informatie die hier wordt verstrekt.
Voert een bewerking uit op een afzonderlijke thread.
public ref class BackgroundWorker : IDisposable
public ref class BackgroundWorker : System::ComponentModel::Component
public class BackgroundWorker : IDisposable
public class BackgroundWorker : System.ComponentModel.Component
type BackgroundWorker = class
interface IDisposable
type BackgroundWorker = class
inherit Component
Public Class BackgroundWorker
Implements IDisposable
Public Class BackgroundWorker
Inherits Component
- Overname
-
BackgroundWorker
- Overname
- Implementeringen
Voorbeelden
In het volgende codevoorbeeld ziet u de basisbeginselen van de BackgroundWorker klasse voor het asynchroon uitvoeren van een tijdrovende bewerking. In de volgende afbeelding ziet u een voorbeeld van de uitvoer.
Als u deze code wilt proberen, maakt u een Windows Forms toepassing. Voeg een Label besturingselement met de naam resultLabel toe en voeg twee Button besturingselementen toe met de naam startAsyncButton en cancelAsyncButton. Gebeurtenis-handlers Click maken voor beide knoppen. Voeg op het tabblad Onderdelen van de Werkset een BackgroundWorker onderdeel toe met de naam backgroundWorker1. Maak DoWork, ProgressChangeden RunWorkerCompleted gebeurtenis-handlers voor de BackgroundWorker. Vervang in de code voor het formulier de bestaande code door de volgende code.
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace BackgroundWorkerSimple;
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = true;
}
void startAsyncButton_Click(object sender, EventArgs e)
{
if (!backgroundWorker1.IsBusy)
{
// Start the asynchronous operation.
backgroundWorker1.RunWorkerAsync();
}
}
void cancelAsyncButton_Click(object sender, EventArgs e)
{
if (backgroundWorker1.WorkerSupportsCancellation)
{
// Cancel the asynchronous operation.
backgroundWorker1.CancelAsync();
}
}
// This event handler is where the time-consuming work is done.
void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
for (int i = 1; i <= 10; i++)
{
if (worker.CancellationPending)
{
e.Cancel = true;
break;
}
else
{
// Perform a time consuming operation and report progress.
System.Threading.Thread.Sleep(500);
worker.ReportProgress(i * 10);
}
}
}
// This event handler updates the progress.
void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) =>
resultLabel.Text = e.ProgressPercentage.ToString() + "%";
// This event handler deals with the results of the background operation.
void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) =>
resultLabel.Text = e.Cancelled ?
"Canceled!"
: e.Error != null ? "Error: " + e.Error.Message : "Done!";
}
Imports System.ComponentModel
Public Class Form1
Public Sub New()
InitializeComponent()
backgroundWorker1.WorkerReportsProgress = True
backgroundWorker1.WorkerSupportsCancellation = True
End Sub
Private Sub startAsyncButton_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles startAsyncButton.Click
If Not backgroundWorker1.IsBusy Then
' Start the asynchronous operation.
backgroundWorker1.RunWorkerAsync()
End If
End Sub
Private Sub cancelAsyncButton_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles cancelAsyncButton.Click
If backgroundWorker1.WorkerSupportsCancellation Then
' Cancel the asynchronous operation.
backgroundWorker1.CancelAsync()
End If
End Sub
' This event handler is where the time-consuming work is done.
Private Sub backgroundWorker1_DoWork(ByVal sender As System.Object, _
ByVal e As DoWorkEventArgs) Handles backgroundWorker1.DoWork
Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
Dim i As Integer
For i = 1 To 10
If (worker.CancellationPending) Then
e.Cancel = True
Exit For
Else
' Perform a time consuming operation and report progress.
System.Threading.Thread.Sleep(500)
worker.ReportProgress(i * 10)
End If
Next
End Sub
' This event handler updates the progress.
Private Sub backgroundWorker1_ProgressChanged(ByVal sender As System.Object, _
ByVal e As ProgressChangedEventArgs) Handles backgroundWorker1.ProgressChanged
resultLabel.Text = (e.ProgressPercentage.ToString() + "%")
End Sub
' This event handler deals with the results of the background operation.
Private Sub backgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, _
ByVal e As RunWorkerCompletedEventArgs) Handles backgroundWorker1.RunWorkerCompleted
If e.Cancelled Then
resultLabel.Text = "Canceled!"
ElseIf e.Error IsNot Nothing Then
resultLabel.Text = "Error: " & e.Error.Message
Else
resultLabel.Text = "Done!"
End If
End Sub
End Class
In het volgende codevoorbeeld ziet u hoe de BackgroundWorker klasse wordt gebruikt voor het asynchroon uitvoeren van een tijdrovende bewerking. In de volgende afbeelding ziet u een voorbeeld van de uitvoer.
De bewerking berekent het geselecteerde Fibonacci-nummer, rapporteert voortgangsupdates wanneer de berekening wordt uitgevoerd en staat toe dat een in behandeling zijnde berekening wordt geannuleerd.
#using <System.Drawing.dll>
#using <System.dll>
#using <System.Windows.Forms.dll>
using namespace System;
using namespace System::Collections;
using namespace System::ComponentModel;
using namespace System::Drawing;
using namespace System::Threading;
using namespace System::Windows::Forms;
public ref class FibonacciForm: public System::Windows::Forms::Form
{
private:
int numberToCompute;
int highestPercentageReached;
System::Windows::Forms::NumericUpDown^ numericUpDown1;
System::Windows::Forms::Button^ startAsyncButton;
System::Windows::Forms::Button^ cancelAsyncButton;
System::Windows::Forms::ProgressBar^ progressBar1;
System::Windows::Forms::Label ^ resultLabel;
System::ComponentModel::BackgroundWorker^ backgroundWorker1;
public:
FibonacciForm()
{
InitializeComponent();
numberToCompute = highestPercentageReached = 0;
InitializeBackgoundWorker();
}
private:
// Set up the BackgroundWorker object by
// attaching event handlers.
void InitializeBackgoundWorker()
{
backgroundWorker1->DoWork += gcnew DoWorkEventHandler( this, &FibonacciForm::backgroundWorker1_DoWork );
backgroundWorker1->RunWorkerCompleted += gcnew RunWorkerCompletedEventHandler( this, &FibonacciForm::backgroundWorker1_RunWorkerCompleted );
backgroundWorker1->ProgressChanged += gcnew ProgressChangedEventHandler( this, &FibonacciForm::backgroundWorker1_ProgressChanged );
}
void startAsyncButton_Click( System::Object^ /*sender*/, System::EventArgs^ /*e*/ )
{
// Reset the text in the result label.
resultLabel->Text = String::Empty;
// Disable the UpDown control until
// the asynchronous operation is done.
this->numericUpDown1->Enabled = false;
// Disable the Start button until
// the asynchronous operation is done.
this->startAsyncButton->Enabled = false;
// Enable the Cancel button while
// the asynchronous operation runs.
this->cancelAsyncButton->Enabled = true;
// Get the value from the UpDown control.
numberToCompute = (int)numericUpDown1->Value;
// Reset the variable for percentage tracking.
highestPercentageReached = 0;
// Start the asynchronous operation.
backgroundWorker1->RunWorkerAsync( numberToCompute );
}
void cancelAsyncButton_Click( System::Object^ /*sender*/, System::EventArgs^ /*e*/ )
{
// Cancel the asynchronous operation.
this->backgroundWorker1->CancelAsync();
// Disable the Cancel button.
cancelAsyncButton->Enabled = false;
}
// This event handler is where the actual,
// potentially time-consuming work is done.
void backgroundWorker1_DoWork( Object^ sender, DoWorkEventArgs^ e )
{
// Get the BackgroundWorker that raised this event.
BackgroundWorker^ worker = dynamic_cast<BackgroundWorker^>(sender);
// Assign the result of the computation
// to the Result property of the DoWorkEventArgs
// object. This is will be available to the
// RunWorkerCompleted eventhandler.
e->Result = ComputeFibonacci( safe_cast<Int32>(e->Argument), worker, e );
}
// This event handler deals with the results of the
// background operation.
void backgroundWorker1_RunWorkerCompleted( Object^ /*sender*/, RunWorkerCompletedEventArgs^ e )
{
// First, handle the case where an exception was thrown.
if ( e->Error != nullptr )
{
MessageBox::Show( e->Error->Message );
}
else
if ( e->Cancelled )
{
// Next, handle the case where the user cancelled
// the operation.
// Note that due to a race condition in
// the DoWork event handler, the Cancelled
// flag may not have been set, even though
// CancelAsync was called.
resultLabel->Text = "Cancelled";
}
else
{
// Finally, handle the case where the operation
// succeeded.
resultLabel->Text = e->Result->ToString();
}
// Enable the UpDown control.
this->numericUpDown1->Enabled = true;
// Enable the Start button.
startAsyncButton->Enabled = true;
// Disable the Cancel button.
cancelAsyncButton->Enabled = false;
}
// This event handler updates the progress bar.
void backgroundWorker1_ProgressChanged( Object^ /*sender*/, ProgressChangedEventArgs^ e )
{
this->progressBar1->Value = e->ProgressPercentage;
}
// This is the method that does the actual work. For this
// example, it computes a Fibonacci number and
// reports progress as it does its work.
long ComputeFibonacci( int n, BackgroundWorker^ worker, DoWorkEventArgs ^ e )
{
// The parameter n must be >= 0 and <= 91.
// Fib(n), with n > 91, overflows a long.
if ( (n < 0) || (n > 91) )
{
throw gcnew ArgumentException( "value must be >= 0 and <= 91","n" );
}
long result = 0;
// Abort the operation if the user has cancelled.
// Note that a call to CancelAsync may have set
// CancellationPending to true just after the
// last invocation of this method exits, so this
// code will not have the opportunity to set the
// DoWorkEventArgs.Cancel flag to true. This means
// that RunWorkerCompletedEventArgs.Cancelled will
// not be set to true in your RunWorkerCompleted
// event handler. This is a race condition.
if ( worker->CancellationPending )
{
e->Cancel = true;
}
else
{
if ( n < 2 )
{
result = 1;
}
else
{
result = ComputeFibonacci( n - 1, worker, e ) + ComputeFibonacci( n - 2, worker, e );
}
// Report progress as a percentage of the total task.
int percentComplete = (int)((float)n / (float)numberToCompute * 100);
if ( percentComplete > highestPercentageReached )
{
highestPercentageReached = percentComplete;
worker->ReportProgress( percentComplete );
}
}
return result;
}
void InitializeComponent()
{
this->numericUpDown1 = gcnew System::Windows::Forms::NumericUpDown;
this->startAsyncButton = gcnew System::Windows::Forms::Button;
this->cancelAsyncButton = gcnew System::Windows::Forms::Button;
this->resultLabel = gcnew System::Windows::Forms::Label;
this->progressBar1 = gcnew System::Windows::Forms::ProgressBar;
this->backgroundWorker1 = gcnew System::ComponentModel::BackgroundWorker;
(dynamic_cast<System::ComponentModel::ISupportInitialize^>(this->numericUpDown1))->BeginInit();
this->SuspendLayout();
//
// numericUpDown1
//
this->numericUpDown1->Location = System::Drawing::Point( 16, 16 );
array<Int32>^temp0 = {91,0,0,0};
this->numericUpDown1->Maximum = System::Decimal( temp0 );
array<Int32>^temp1 = {1,0,0,0};
this->numericUpDown1->Minimum = System::Decimal( temp1 );
this->numericUpDown1->Name = "numericUpDown1";
this->numericUpDown1->Size = System::Drawing::Size( 80, 20 );
this->numericUpDown1->TabIndex = 0;
array<Int32>^temp2 = {1,0,0,0};
this->numericUpDown1->Value = System::Decimal( temp2 );
//
// startAsyncButton
//
this->startAsyncButton->Location = System::Drawing::Point( 16, 72 );
this->startAsyncButton->Name = "startAsyncButton";
this->startAsyncButton->Size = System::Drawing::Size( 120, 23 );
this->startAsyncButton->TabIndex = 1;
this->startAsyncButton->Text = "Start Async";
this->startAsyncButton->Click += gcnew System::EventHandler( this, &FibonacciForm::startAsyncButton_Click );
//
// cancelAsyncButton
//
this->cancelAsyncButton->Enabled = false;
this->cancelAsyncButton->Location = System::Drawing::Point( 153, 72 );
this->cancelAsyncButton->Name = "cancelAsyncButton";
this->cancelAsyncButton->Size = System::Drawing::Size( 119, 23 );
this->cancelAsyncButton->TabIndex = 2;
this->cancelAsyncButton->Text = "Cancel Async";
this->cancelAsyncButton->Click += gcnew System::EventHandler( this, &FibonacciForm::cancelAsyncButton_Click );
//
// resultLabel
//
this->resultLabel->BorderStyle = System::Windows::Forms::BorderStyle::Fixed3D;
this->resultLabel->Location = System::Drawing::Point( 112, 16 );
this->resultLabel->Name = "resultLabel";
this->resultLabel->Size = System::Drawing::Size( 160, 23 );
this->resultLabel->TabIndex = 3;
this->resultLabel->Text = "(no result)";
this->resultLabel->TextAlign = System::Drawing::ContentAlignment::MiddleCenter;
//
// progressBar1
//
this->progressBar1->Location = System::Drawing::Point( 18, 48 );
this->progressBar1->Name = "progressBar1";
this->progressBar1->Size = System::Drawing::Size( 256, 8 );
this->progressBar1->Step = 2;
this->progressBar1->TabIndex = 4;
//
// backgroundWorker1
//
this->backgroundWorker1->WorkerReportsProgress = true;
this->backgroundWorker1->WorkerSupportsCancellation = true;
//
// FibonacciForm
//
this->ClientSize = System::Drawing::Size( 292, 118 );
this->Controls->Add( this->progressBar1 );
this->Controls->Add( this->resultLabel );
this->Controls->Add( this->cancelAsyncButton );
this->Controls->Add( this->startAsyncButton );
this->Controls->Add( this->numericUpDown1 );
this->Name = "FibonacciForm";
this->Text = "Fibonacci Calculator";
(dynamic_cast<System::ComponentModel::ISupportInitialize^>(this->numericUpDown1))->EndInit();
this->ResumeLayout( false );
}
};
[STAThread]
int main()
{
Application::Run( gcnew FibonacciForm );
}
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace BackgroundWorkerExample;
public class FibonacciForm : Form
{
int numberToCompute;
int highestPercentageReached;
NumericUpDown numericUpDown1;
Button startAsyncButton;
Button cancelAsyncButton;
ProgressBar progressBar1;
Label resultLabel;
BackgroundWorker backgroundWorker1;
public FibonacciForm()
{
InitializeComponent();
InitializeBackgroundWorker();
}
// Set up the BackgroundWorker object by
// attaching event handlers.
void InitializeBackgroundWorker()
{
backgroundWorker1.DoWork +=
backgroundWorker1_DoWork;
backgroundWorker1.RunWorkerCompleted +=
backgroundWorker1_RunWorkerCompleted;
backgroundWorker1.ProgressChanged +=
backgroundWorker1_ProgressChanged;
}
void startAsyncButton_Click(object sender,
EventArgs e)
{
// Reset the text in the result label.
resultLabel.Text = string.Empty;
// Disable the UpDown control until
// the asynchronous operation is done.
numericUpDown1.Enabled = false;
// Disable the Start button until
// the asynchronous operation is done.
startAsyncButton.Enabled = false;
// Enable the Cancel button while
// the asynchronous operation runs.
cancelAsyncButton.Enabled = true;
// Get the value from the UpDown control.
numberToCompute = (int)numericUpDown1.Value;
// Reset the variable for percentage tracking.
highestPercentageReached = 0;
// Start the asynchronous operation.
backgroundWorker1.RunWorkerAsync(numberToCompute);
}
void cancelAsyncButton_Click(object sender,
EventArgs e)
{
// Cancel the asynchronous operation.
backgroundWorker1.CancelAsync();
// Disable the Cancel button.
cancelAsyncButton.Enabled = false;
}
// This event handler is where the actual,
// potentially time-consuming work is done.
void backgroundWorker1_DoWork(object sender,
DoWorkEventArgs e)
{
// Get the BackgroundWorker that raised this event.
BackgroundWorker worker = sender as BackgroundWorker;
// Assign the result of the computation
// to the Result property of the DoWorkEventArgs
// object. This is will be available to the
// RunWorkerCompleted eventhandler.
e.Result = ComputeFibonacci((int)e.Argument, worker, e);
}
// This event handler deals with the results of the
// background operation.
void backgroundWorker1_RunWorkerCompleted(
object sender, RunWorkerCompletedEventArgs e)
{
// First, handle the case where an exception was thrown.
if (e.Error != null)
{
_ = MessageBox.Show(e.Error.Message);
}
else if (e.Cancelled)
{
// Next, handle the case where the user canceled
// the operation.
// Note that due to a race condition in
// the DoWork event handler, the Cancelled
// flag may not have been set, even though
// CancelAsync was called.
resultLabel.Text = "Canceled";
}
else
{
// Finally, handle the case where the operation
// succeeded.
resultLabel.Text = e.Result.ToString();
}
// Enable the UpDown control.
numericUpDown1.Enabled = true;
// Enable the Start button.
startAsyncButton.Enabled = true;
// Disable the Cancel button.
cancelAsyncButton.Enabled = false;
}
// This event handler updates the progress bar.
void backgroundWorker1_ProgressChanged(object sender,
ProgressChangedEventArgs e) => progressBar1.Value = e.ProgressPercentage;
// This is the method that does the actual work. For this
// example, it computes a Fibonacci number and
// reports progress as it does its work.
long ComputeFibonacci(int n, BackgroundWorker worker, DoWorkEventArgs e)
{
// The parameter n must be >= 0 and <= 91.
// Fib(n), with n > 91, overflows a long.
if (n is < 0 or > 91)
{
throw new ArgumentException(
"value must be >= 0 and <= 91", nameof(n));
}
long result = 0;
// Abort the operation if the user has canceled.
// Note that a call to CancelAsync may have set
// CancellationPending to true just after the
// last invocation of this method exits, so this
// code will not have the opportunity to set the
// DoWorkEventArgs.Cancel flag to true. This means
// that RunWorkerCompletedEventArgs.Cancelled will
// not be set to true in your RunWorkerCompleted
// event handler. This is a race condition.
if (worker.CancellationPending)
{
e.Cancel = true;
}
else
{
result = n < 2
? 1
: ComputeFibonacci(n - 1, worker, e) +
ComputeFibonacci(n - 2, worker, e);
// Report progress as a percentage of the total task.
int percentComplete =
(int)(n / (float)numberToCompute * 100);
if (percentComplete > highestPercentageReached)
{
highestPercentageReached = percentComplete;
worker.ReportProgress(percentComplete);
}
}
return result;
}
#region Windows Form Designer generated code
void InitializeComponent()
{
numericUpDown1 = new NumericUpDown();
startAsyncButton = new Button();
cancelAsyncButton = new Button();
resultLabel = new Label();
progressBar1 = new ProgressBar();
backgroundWorker1 = new BackgroundWorker();
((ISupportInitialize)numericUpDown1).BeginInit();
SuspendLayout();
//
// numericUpDown1
//
numericUpDown1.Location = new Point(16, 16);
numericUpDown1.Maximum = new decimal(new int[] {
91,
0,
0,
0});
numericUpDown1.Minimum = new decimal(new int[] {
1,
0,
0,
0});
numericUpDown1.Name = "numericUpDown1";
numericUpDown1.Size = new Size(80, 20);
numericUpDown1.TabIndex = 0;
numericUpDown1.Value = new decimal(new int[] {
1,
0,
0,
0});
//
// startAsyncButton
//
startAsyncButton.Location = new Point(16, 72);
startAsyncButton.Name = "startAsyncButton";
startAsyncButton.Size = new Size(120, 23);
startAsyncButton.TabIndex = 1;
startAsyncButton.Text = "Start Async";
startAsyncButton.Click += startAsyncButton_Click;
//
// cancelAsyncButton
//
cancelAsyncButton.Enabled = false;
cancelAsyncButton.Location = new Point(153, 72);
cancelAsyncButton.Name = "cancelAsyncButton";
cancelAsyncButton.Size = new Size(119, 23);
cancelAsyncButton.TabIndex = 2;
cancelAsyncButton.Text = "Cancel Async";
cancelAsyncButton.Click += cancelAsyncButton_Click;
//
// resultLabel
//
resultLabel.BorderStyle = BorderStyle.Fixed3D;
resultLabel.Location = new Point(112, 16);
resultLabel.Name = "resultLabel";
resultLabel.Size = new Size(160, 23);
resultLabel.TabIndex = 3;
resultLabel.Text = "(no result)";
resultLabel.TextAlign = ContentAlignment.MiddleCenter;
//
// progressBar1
//
progressBar1.Location = new Point(18, 48);
progressBar1.Name = "progressBar1";
progressBar1.Size = new Size(256, 8);
progressBar1.Step = 2;
progressBar1.TabIndex = 4;
//
// backgroundWorker1
//
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = true;
//
// FibonacciForm
//
ClientSize = new Size(1794, 927);
Controls.Add(progressBar1);
Controls.Add(resultLabel);
Controls.Add(cancelAsyncButton);
Controls.Add(startAsyncButton);
Controls.Add(numericUpDown1);
Name = "FibonacciForm";
Text = "Fibonacci Calculator";
((ISupportInitialize)numericUpDown1).EndInit();
ResumeLayout(false);
}
#endregion
[STAThread]
static void Main() => Application.Run(new FibonacciForm());
}
Imports System.ComponentModel
Imports System.Windows.Forms
Public Class FibonacciForm
Inherits Form
Private numberToCompute As Integer = 0
Private highestPercentageReached As Integer = 0
Private numericUpDown1 As NumericUpDown
Private WithEvents startAsyncButton As Button
Private WithEvents cancelAsyncButton As Button
Private progressBar1 As ProgressBar
Private resultLabel As Label
Private WithEvents backgroundWorker1 As System.ComponentModel.BackgroundWorker
Public Sub New()
InitializeComponent()
End Sub
Private Sub startAsyncButton_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) _
Handles startAsyncButton.Click
' Reset the text in the result label.
resultLabel.Text = [String].Empty
' Disable the UpDown control until
' the asynchronous operation is done.
numericUpDown1.Enabled = False
' Disable the Start button until
' the asynchronous operation is done.
startAsyncButton.Enabled = False
' Enable the Cancel button while
' the asynchronous operation runs.
cancelAsyncButton.Enabled = True
' Get the value from the UpDown control.
numberToCompute = CInt(numericUpDown1.Value)
' Reset the variable for percentage tracking.
highestPercentageReached = 0
' Start the asynchronous operation.
backgroundWorker1.RunWorkerAsync(numberToCompute)
End Sub
Private Sub cancelAsyncButton_Click(
ByVal sender As System.Object,
ByVal e As System.EventArgs) _
Handles cancelAsyncButton.Click
' Cancel the asynchronous operation.
backgroundWorker1.CancelAsync()
' Disable the Cancel button.
cancelAsyncButton.Enabled = False
End Sub
' This event handler is where the actual work is done.
Private Sub backgroundWorker1_DoWork(
ByVal sender As Object,
ByVal e As DoWorkEventArgs) _
Handles backgroundWorker1.DoWork
' Get the BackgroundWorker object that raised this event.
Dim worker As BackgroundWorker =
CType(sender, BackgroundWorker)
' Assign the result of the computation
' to the Result property of the DoWorkEventArgs
' object. This is will be available to the
' RunWorkerCompleted eventhandler.
e.Result = ComputeFibonacci(e.Argument, worker, e)
End Sub
' This event handler deals with the results of the
' background operation.
Private Sub backgroundWorker1_RunWorkerCompleted(
ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) _
Handles backgroundWorker1.RunWorkerCompleted
' First, handle the case where an exception was thrown.
If (e.Error IsNot Nothing) Then
MessageBox.Show(e.Error.Message)
ElseIf e.Cancelled Then
' Next, handle the case where the user canceled the
' operation.
' Note that due to a race condition in
' the DoWork event handler, the Cancelled
' flag may not have been set, even though
' CancelAsync was called.
resultLabel.Text = "Canceled"
Else
' Finally, handle the case where the operation succeeded.
resultLabel.Text = e.Result.ToString()
End If
' Enable the UpDown control.
numericUpDown1.Enabled = True
' Enable the Start button.
startAsyncButton.Enabled = True
' Disable the Cancel button.
cancelAsyncButton.Enabled = False
End Sub
' This event handler updates the progress bar.
Private Sub backgroundWorker1_ProgressChanged(
ByVal sender As Object, ByVal e As ProgressChangedEventArgs) _
Handles backgroundWorker1.ProgressChanged
progressBar1.Value = e.ProgressPercentage
End Sub
' This is the method that does the actual work. For this
' example, it computes a Fibonacci number and
' reports progress as it does its work.
Function ComputeFibonacci(
ByVal n As Integer,
ByVal worker As BackgroundWorker,
ByVal e As DoWorkEventArgs) As Long
' The parameter n must be >= 0 and <= 91.
' Fib(n), with n > 91, overflows a long.
If n < 0 OrElse n > 91 Then
Throw New ArgumentException(
"value must be >= 0 and <= 91", "n")
End If
Dim result As Long = 0
' Abort the operation if the user has canceled.
' Note that a call to CancelAsync may have set
' CancellationPending to true just after the
' last invocation of this method exits, so this
' code will not have the opportunity to set the
' DoWorkEventArgs.Cancel flag to true. This means
' that RunWorkerCompletedEventArgs.Cancelled will
' not be set to true in your RunWorkerCompleted
' event handler. This is a race condition.
If worker.CancellationPending Then
e.Cancel = True
Else
If n < 2 Then
result = 1
Else
result = ComputeFibonacci(n - 1, worker, e) +
ComputeFibonacci(n - 2, worker, e)
End If
' Report progress as a percentage of the total task.
Dim percentComplete As Integer =
CSng(n) / CSng(numberToCompute) * 100
If percentComplete > highestPercentageReached Then
highestPercentageReached = percentComplete
worker.ReportProgress(percentComplete)
End If
End If
Return result
End Function
Private Sub InitializeComponent()
numericUpDown1 = New NumericUpDown
startAsyncButton = New Button
cancelAsyncButton = New Button
resultLabel = New Label
progressBar1 = New ProgressBar
backgroundWorker1 = New System.ComponentModel.BackgroundWorker
CType(numericUpDown1, System.ComponentModel.ISupportInitialize).BeginInit()
SuspendLayout()
'
'numericUpDown1
'
numericUpDown1.Location = New System.Drawing.Point(16, 16)
numericUpDown1.Maximum = New Decimal(New Integer() {91, 0, 0, 0})
numericUpDown1.Minimum = New Decimal(New Integer() {1, 0, 0, 0})
numericUpDown1.Name = "numericUpDown1"
numericUpDown1.Size = New System.Drawing.Size(80, 20)
numericUpDown1.TabIndex = 0
numericUpDown1.Value = New Decimal(New Integer() {1, 0, 0, 0})
'
'startAsyncButton
'
startAsyncButton.Location = New System.Drawing.Point(16, 72)
startAsyncButton.Name = "startAsyncButton"
startAsyncButton.Size = New System.Drawing.Size(120, 23)
startAsyncButton.TabIndex = 1
startAsyncButton.Text = "Start Async"
'
'cancelAsyncButton
'
cancelAsyncButton.Enabled = False
cancelAsyncButton.Location = New System.Drawing.Point(153, 72)
cancelAsyncButton.Name = "cancelAsyncButton"
cancelAsyncButton.Size = New System.Drawing.Size(119, 23)
cancelAsyncButton.TabIndex = 2
cancelAsyncButton.Text = "Cancel Async"
'
'resultLabel
'
resultLabel.BorderStyle = BorderStyle.Fixed3D
resultLabel.Location = New System.Drawing.Point(112, 16)
resultLabel.Name = "resultLabel"
resultLabel.Size = New System.Drawing.Size(160, 23)
resultLabel.TabIndex = 3
resultLabel.Text = "(no result)"
resultLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
'
'progressBar1
'
progressBar1.Location = New System.Drawing.Point(18, 48)
progressBar1.Name = "progressBar1"
progressBar1.Size = New System.Drawing.Size(256, 8)
progressBar1.TabIndex = 4
'
'backgroundWorker1
'
backgroundWorker1.WorkerReportsProgress = True
backgroundWorker1.WorkerSupportsCancellation = True
'
'FibonacciForm
'
ClientSize = New System.Drawing.Size(292, 118)
Controls.Add(progressBar1)
Controls.Add(resultLabel)
Controls.Add(cancelAsyncButton)
Controls.Add(startAsyncButton)
Controls.Add(numericUpDown1)
Name = "FibonacciForm"
Text = "Fibonacci Calculator"
CType(numericUpDown1, System.ComponentModel.ISupportInitialize).EndInit()
ResumeLayout(False)
End Sub
<STAThread()> _
Shared Sub Main()
Application.Run(New FibonacciForm)
End Sub
End Class
Opmerkingen
Met de BackgroundWorker klasse kunt u een bewerking uitvoeren op een afzonderlijke, toegewezen thread. Tijdrovende bewerkingen, zoals downloads en databasetransacties, kunnen ertoe leiden dat uw gebruikersinterface (UI) lijkt alsof deze niet meer reageert terwijl ze worden uitgevoerd. Wanneer u een responsieve gebruikersinterface wilt en u te maken hebt met lange vertragingen die zijn gekoppeld aan dergelijke bewerkingen, biedt de BackgroundWorker klasse een handige oplossing.
Als u een tijdrovende bewerking op de achtergrond wilt uitvoeren, maakt u een BackgroundWorker gebeurtenis die de voortgang van uw bewerking rapporteert en signaleert wanneer uw bewerking is voltooid. U kunt het BackgroundWorker programmatisch maken of u kunt het naar uw formulier slepen vanaf het tabblad Onderdelen van de werkset. Als u de BackgroundWorker in de Windows Forms Designer maakt, wordt deze weergegeven in het onderdeelvak en worden de eigenschappen ervan weergegeven in de venster Eigenschappen.
Als u een achtergrondbewerking wilt instellen, voegt u een gebeurtenis-handler voor de DoWork gebeurtenis toe. Roep uw tijdrovende bewerking aan in deze gebeurtenis-handler. Als u de bewerking wilt starten, roept u het aan RunWorkerAsync. Als u meldingen van voortgangsupdates wilt ontvangen, moet u de ProgressChanged gebeurtenis afhandelen. Als u een melding wilt ontvangen wanneer de bewerking is voltooid, moet u de RunWorkerCompleted gebeurtenis afhandelen.
Opmerking
U moet ervoor zorgen dat u geen gebruikersinterfaceobjecten in uw DoWork gebeurtenis-handler bewerkt. In plaats daarvan communiceert u met de gebruikersinterface via de ProgressChanged en RunWorkerCompleted gebeurtenissen.
BackgroundWorker gebeurtenissen zijn niet marshaled over AppDomain grenzen heen. Gebruik geen BackgroundWorker onderdeel voor het uitvoeren van multithreaded bewerkingen in meer dan één AppDomain.
Als voor uw achtergrondbewerking een parameter is vereist, roept RunWorkerAsync u de parameter aan. In de DoWork gebeurtenis-handler kunt u de parameter uit de DoWorkEventArgs.Argument eigenschap extraheren.
Zie BackgroundWorker voor meer informatie.
Constructors
| Name | Description |
|---|---|
| BackgroundWorker() |
Initialiseert een nieuw exemplaar van de BackgroundWorker klasse. |
Eigenschappen
| Name | Description |
|---|---|
| CancellationPending |
Hiermee wordt een waarde opgehaald die aangeeft of de toepassing annulering van een achtergrondbewerking heeft aangevraagd. |
| CanRaiseEvents |
Hiermee wordt een waarde opgehaald die aangeeft of het onderdeel een gebeurtenis kan genereren. (Overgenomen van Component) |
| Container |
Hiermee haalt u het IContainer bestand op dat de Component. (Overgenomen van Component) |
| DesignMode |
Hiermee wordt een waarde opgehaald die aangeeft of de Component momenteel in de ontwerpmodus is. (Overgenomen van Component) |
| Events |
Hiermee haalt u de lijst met gebeurtenis-handlers op die aan dit Componentbestand zijn gekoppeld. (Overgenomen van Component) |
| IsBusy |
Hiermee wordt een waarde opgehaald die aangeeft of er BackgroundWorker een asynchrone bewerking wordt uitgevoerd. |
| Site |
Haalt of stelt de ISite van de Component. (Overgenomen van Component) |
| WorkerReportsProgress |
Hiermee wordt een waarde opgehaald of ingesteld die aangeeft of de BackgroundWorker voortgangsupdates kunnen worden gemeld. |
| WorkerSupportsCancellation |
Hiermee wordt een waarde opgehaald of ingesteld die aangeeft of de BackgroundWorker annulering asynchroon ondersteunt. |
Methoden
| Name | Description |
|---|---|
| CancelAsync() |
Aanvraag voor annulering van een in behandeling zijnde achtergrondbewerking. |
| CreateObjRef(Type) |
Hiermee maakt u een object dat alle relevante informatie bevat die nodig is om een proxy te genereren die wordt gebruikt om te communiceren met een extern object. (Overgenomen van MarshalByRefObject) |
| Dispose() |
Voert door de toepassing gedefinieerde taken uit die zijn gekoppeld aan het vrijmaken, vrijgeven of opnieuw instellen van onbeheerde resources. |
| Dispose() |
Alle resources die worden gebruikt door de Component. (Overgenomen van Component) |
| Dispose(Boolean) |
Deze methode doet niets. |
| Dispose(Boolean) |
Publiceert de niet-beheerde resources die worden gebruikt door de Component beheerde resources en brengt eventueel de beheerde resources vrij. (Overgenomen van Component) |
| Equals(Object) |
Bepaalt of het opgegeven object gelijk is aan het huidige object. (Overgenomen van Object) |
| GetHashCode() |
Fungeert als de standaardhashfunctie. (Overgenomen van Object) |
| GetLifetimeService() |
Hiermee haalt u het huidige levensduurserviceobject op waarmee het levensduurbeleid voor dit exemplaar wordt beheerd. (Overgenomen van MarshalByRefObject) |
| GetService(Type) |
Hiermee wordt een object geretourneerd dat een service vertegenwoordigt die wordt geleverd door of door de Component service Container. (Overgenomen van Component) |
| GetType() |
Hiermee haalt u de Type huidige instantie op. (Overgenomen van Object) |
| InitializeLifetimeService() |
Hiermee haalt u een levensduurserviceobject op om het levensduurbeleid voor dit exemplaar te beheren. (Overgenomen van MarshalByRefObject) |
| MemberwiseClone() |
Hiermee maakt u een ondiepe kopie van de huidige Object. (Overgenomen van Object) |
| MemberwiseClone(Boolean) |
Hiermee maakt u een ondiepe kopie van het huidige MarshalByRefObject object. (Overgenomen van MarshalByRefObject) |
| OnDoWork(DoWorkEventArgs) |
Hiermee wordt de DoWork gebeurtenis gegenereerd. |
| OnProgressChanged(ProgressChangedEventArgs) |
Hiermee wordt de ProgressChanged gebeurtenis gegenereerd. |
| OnRunWorkerCompleted(RunWorkerCompletedEventArgs) |
Hiermee wordt de RunWorkerCompleted gebeurtenis gegenereerd. |
| ReportProgress(Int32, Object) |
Hiermee wordt de ProgressChanged gebeurtenis gegenereerd. |
| ReportProgress(Int32) |
Hiermee wordt de ProgressChanged gebeurtenis gegenereerd. |
| RunWorkerAsync() |
Hiermee start u de uitvoering van een achtergrondbewerking. |
| RunWorkerAsync(Object) |
Hiermee start u de uitvoering van een achtergrondbewerking. |
| ToString() |
Retourneert een tekenreeks die het huidige object vertegenwoordigt. (Overgenomen van Object) |
| ToString() |
Retourneert een String met de naam van de Component, indien van toepassing. Deze methode mag niet worden overschreven. (Overgenomen van Component) |
gebeurtenis
| Name | Description |
|---|---|
| Disposed |
Treedt op wanneer het onderdeel wordt verwijderd door een aanroep naar de Dispose() methode. (Overgenomen van Component) |
| DoWork |
Treedt op wanneer RunWorkerAsync() wordt aangeroepen. |
| ProgressChanged |
Treedt op wanneer ReportProgress(Int32) wordt aangeroepen. |
| RunWorkerCompleted |
Treedt op wanneer de achtergrondbewerking is voltooid, is geannuleerd of een uitzondering heeft gegenereerd. |
Van toepassing op
Zie ook
- Handleiding: Een bewerking uitvoeren op de achtergrond
- Aanbevolen procedures voor beheerd draadbeheer
- Procedure: Een bestand downloaden op de achtergrond