注意:此类在 .NET Framework 2.0 版中是新增的。
在单独的线程上执行操作。
命名空间:System.ComponentModel
程序集:System(在 system.dll 中)
BackgroundWorker 类允许您在单独的专用线程上运行操作。耗时的操作(如下载和数据库事务)在长时间运行时可能会导致用户界面 (UI) 似乎处于停止响应状态。如果您需要能进行响应的用户界面,而且面临与这类操作相关的长时间延迟,则可以使用 BackgroundWorker 类方便地解决问题。
若要在后台执行耗时的操作,请创建一个 BackgroundWorker,侦听那些报告操作进度并在操作完成时发出信号的事件。可以通过编程方式创建 BackgroundWorker,也可以将它从“工具箱”的“组件”选项卡中拖到窗体上。如果在 Windows 窗体设计器中创建 BackgroundWorker,则它会出现在组件栏中,而且它的属性会显示在“属性”窗口中。
若要设置后台操作,请为 DoWork 事件添加一个事件处理程序。在此事件处理程序中调用耗时的操作。若要启动该操作,请调用 RunWorkerAsync。若要收到进度更新通知,请对 ProgressChanged 事件进行处理。若要在操作完成时收到通知,请对 RunWorkerCompleted 事件进行处理。
注意 |
---|
您必须非常小心,确保在 DoWork 事件处理程序中不操作任何用户界面对象。而应该通过 ProgressChanged 和 RunWorkerCompleted 事件与用户界面进行通信。 BackgroundWorker 事件不跨 AppDomain 边界进行封送处理。请不要使用 BackgroundWorker 组件在多个 AppDomain 中执行多线程操作。 |
如果后台操作需要参数,请在调用 RunWorkerAsync 时给出参数。在 DoWork 事件处理程序内部,可以从 DoWorkEventArgs.Argument 属性中提取该参数。
有关 BackgroundWorker 的更多信息,请参见 如何:在后台运行操作。
注意 |
---|
应用于此类的 HostProtectionAttribute 属性 (Attribute) 具有以下 Resources 属性 (Property) 值:SharedState。HostProtectionAttribute 不影响桌面应用程序(这些应用程序通常通过双击图标、键入命令或在浏览器中输入 URL 来启动)。有关更多信息,请参见 HostProtectionAttribute 类或 SQL Server 编程和宿主保护属性。 |
下面的代码示例演示如何使用 BackgroundWorker 类异步执行耗时的操作。该操作计算选定的斐波纳契数,在计算过程中报告进度更新,并允许取消挂起的计算。
Imports System Imports System.Collections Imports System.ComponentModel Imports System.Drawing Imports System.Threading Imports System.Windows.Forms Public Class FibonacciForm Inherits System.Windows.Forms.Form Private numberToCompute As Integer = 0 Private highestPercentageReached As Integer = 0 Private numericUpDown1 As System.Windows.Forms.NumericUpDown Private WithEvents startAsyncButton As System.Windows.Forms.Button Private WithEvents cancelAsyncButton As System.Windows.Forms.Button Private progressBar1 As System.Windows.Forms.ProgressBar Private resultLabel As System.Windows.Forms.Label Private WithEvents backgroundWorker1 As System.ComponentModel.BackgroundWorker Public Sub New() InitializeComponent() End Sub 'New 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. Me.numericUpDown1.Enabled = False ' Disable the Start button until ' the asynchronous operation is done. Me.startAsyncButton.Enabled = False ' Enable the Cancel button while ' the asynchronous operation runs. Me.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. Me.backgroundWorker1.CancelAsync() ' Disable the Cancel button. cancelAsyncButton.Enabled = False End Sub 'cancelAsyncButton_Click ' 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 'backgroundWorker1_DoWork ' 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 Not (e.Error Is 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. Me.numericUpDown1.Enabled = True ' Enable the Start button. startAsyncButton.Enabled = True ' Disable the Cancel button. cancelAsyncButton.Enabled = False End Sub 'backgroundWorker1_RunWorkerCompleted ' This event handler updates the progress bar. Private Sub backgroundWorker1_ProgressChanged( _ ByVal sender As Object, ByVal e As ProgressChangedEventArgs) _ Handles backgroundWorker1.ProgressChanged Me.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() Me.numericUpDown1 = New System.Windows.Forms.NumericUpDown Me.startAsyncButton = New System.Windows.Forms.Button Me.cancelAsyncButton = New System.Windows.Forms.Button Me.resultLabel = New System.Windows.Forms.Label Me.progressBar1 = New System.Windows.Forms.ProgressBar Me.backgroundWorker1 = New System.ComponentModel.BackgroundWorker CType(Me.numericUpDown1, System.ComponentModel.ISupportInitialize).BeginInit() Me.SuspendLayout() ' 'numericUpDown1 ' Me.numericUpDown1.Location = New System.Drawing.Point(16, 16) Me.numericUpDown1.Maximum = New Decimal(New Integer() {91, 0, 0, 0}) Me.numericUpDown1.Minimum = New Decimal(New Integer() {1, 0, 0, 0}) Me.numericUpDown1.Name = "numericUpDown1" Me.numericUpDown1.Size = New System.Drawing.Size(80, 20) Me.numericUpDown1.TabIndex = 0 Me.numericUpDown1.Value = New Decimal(New Integer() {1, 0, 0, 0}) ' 'startAsyncButton ' Me.startAsyncButton.Location = New System.Drawing.Point(16, 72) Me.startAsyncButton.Name = "startAsyncButton" Me.startAsyncButton.Size = New System.Drawing.Size(120, 23) Me.startAsyncButton.TabIndex = 1 Me.startAsyncButton.Text = "Start Async" ' 'cancelAsyncButton ' Me.cancelAsyncButton.Enabled = False Me.cancelAsyncButton.Location = New System.Drawing.Point(153, 72) Me.cancelAsyncButton.Name = "cancelAsyncButton" Me.cancelAsyncButton.Size = New System.Drawing.Size(119, 23) Me.cancelAsyncButton.TabIndex = 2 Me.cancelAsyncButton.Text = "Cancel Async" ' 'resultLabel ' Me.resultLabel.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D Me.resultLabel.Location = New System.Drawing.Point(112, 16) Me.resultLabel.Name = "resultLabel" Me.resultLabel.Size = New System.Drawing.Size(160, 23) Me.resultLabel.TabIndex = 3 Me.resultLabel.Text = "(no result)" Me.resultLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter ' 'progressBar1 ' Me.progressBar1.Location = New System.Drawing.Point(18, 48) Me.progressBar1.Name = "progressBar1" Me.progressBar1.Size = New System.Drawing.Size(256, 8) Me.progressBar1.TabIndex = 4 ' 'backgroundWorker1 ' Me.backgroundWorker1.WorkerReportsProgress = True Me.backgroundWorker1.WorkerSupportsCancellation = True ' 'FibonacciForm ' Me.ClientSize = New System.Drawing.Size(292, 118) Me.Controls.Add(Me.progressBar1) Me.Controls.Add(Me.resultLabel) Me.Controls.Add(Me.cancelAsyncButton) Me.Controls.Add(Me.startAsyncButton) Me.Controls.Add(Me.numericUpDown1) Me.Name = "FibonacciForm" Me.Text = "Fibonacci Calculator" CType(Me.numericUpDown1, System.ComponentModel.ISupportInitialize).EndInit() Me.ResumeLayout(False) End Sub 'InitializeComponent <STAThread()> _ Shared Sub Main() Application.Run(New FibonacciForm) End Sub 'Main End Class 'FibonacciForm
using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Threading; using System.Windows.Forms; namespace BackgroundWorkerExample { public class FibonacciForm : System.Windows.Forms.Form { private int numberToCompute = 0; private int highestPercentageReached = 0; private System.Windows.Forms.NumericUpDown numericUpDown1; private System.Windows.Forms.Button startAsyncButton; private System.Windows.Forms.Button cancelAsyncButton; private System.Windows.Forms.ProgressBar progressBar1; private System.Windows.Forms.Label resultLabel; private System.ComponentModel.BackgroundWorker backgroundWorker1; public FibonacciForm() { InitializeComponent(); InitializeBackgoundWorker(); } // Set up the BackgroundWorker object by // attaching event handlers. private void InitializeBackgoundWorker() { backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork); backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler( backgroundWorker1_RunWorkerCompleted); backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler( backgroundWorker1_ProgressChanged); } private 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); } private 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. private 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. private 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. 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. private 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 new ArgumentException( "value must be >= 0 and <= 91", "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 { 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; } #region Windows Form Designer generated code private void InitializeComponent() { this.numericUpDown1 = new System.Windows.Forms.NumericUpDown(); this.startAsyncButton = new System.Windows.Forms.Button(); this.cancelAsyncButton = new System.Windows.Forms.Button(); this.resultLabel = new System.Windows.Forms.Label(); this.progressBar1 = new System.Windows.Forms.ProgressBar(); this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker(); ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit(); this.SuspendLayout(); // // numericUpDown1 // this.numericUpDown1.Location = new System.Drawing.Point(16, 16); this.numericUpDown1.Maximum = new System.Decimal(new int[] { 91, 0, 0, 0}); this.numericUpDown1.Minimum = new System.Decimal(new int[] { 1, 0, 0, 0}); this.numericUpDown1.Name = "numericUpDown1"; this.numericUpDown1.Size = new System.Drawing.Size(80, 20); this.numericUpDown1.TabIndex = 0; this.numericUpDown1.Value = new System.Decimal(new int[] { 1, 0, 0, 0}); // // startAsyncButton // this.startAsyncButton.Location = new System.Drawing.Point(16, 72); this.startAsyncButton.Name = "startAsyncButton"; this.startAsyncButton.Size = new System.Drawing.Size(120, 23); this.startAsyncButton.TabIndex = 1; this.startAsyncButton.Text = "Start Async"; this.startAsyncButton.Click += new System.EventHandler(this.startAsyncButton_Click); // // cancelAsyncButton // this.cancelAsyncButton.Enabled = false; this.cancelAsyncButton.Location = new System.Drawing.Point(153, 72); this.cancelAsyncButton.Name = "cancelAsyncButton"; this.cancelAsyncButton.Size = new System.Drawing.Size(119, 23); this.cancelAsyncButton.TabIndex = 2; this.cancelAsyncButton.Text = "Cancel Async"; this.cancelAsyncButton.Click += new System.EventHandler(this.cancelAsyncButton_Click); // // resultLabel // this.resultLabel.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; this.resultLabel.Location = new System.Drawing.Point(112, 16); this.resultLabel.Name = "resultLabel"; this.resultLabel.Size = new 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 = new System.Drawing.Point(18, 48); this.progressBar1.Name = "progressBar1"; this.progressBar1.Size = new 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 = new 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"; ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit(); this.ResumeLayout(false); } #endregion [STAThread] static void Main() { Application.Run(new FibonacciForm()); } } }
#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 ); }
import System.* ; import System.Collections.* ; import System.ComponentModel.* ; import System.Drawing.* ; import System.Threading.* ; import System.Windows.Forms.* ; public class FibonacciForm extends System.Windows.Forms.Form { private int numberToCompute = 0; private int highestPercentageReached = 0; private System.Windows.Forms.NumericUpDown numericUpDown1; private System.Windows.Forms.Button startAsyncButton; private System.Windows.Forms.Button cancelAsyncButton; private System.Windows.Forms.ProgressBar progressBar1; private System.Windows.Forms.Label resultLabel; private System.ComponentModel.BackgroundWorker backgroundWorker1; public FibonacciForm() { InitializeComponent(); InitializeBackgoundWorker(); } //FibonacciForm // Set up the BackgroundWorker object by // attaching event handlers. private void InitializeBackgoundWorker() { backgroundWorker1.add_DoWork(new DoWorkEventHandler( backgroundWorker1_DoWork)); backgroundWorker1.add_RunWorkerCompleted( new RunWorkerCompletedEventHandler( backgroundWorker1_RunWorkerCompleted)); backgroundWorker1.add_ProgressChanged( new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged)); } //InitializeBackgoundWorker private void startAsyncButton_Click(Object sender, EventArgs e) { // Reset the text in the result label. resultLabel.set_Text(String.Empty); // Disable the UpDown control until // the asynchronous operation is done. this.numericUpDown1.set_Enabled(false); // Disable the Start button until // the asynchronous operation is done. this.startAsyncButton.set_Enabled(false); // Enable the Cancel button while // the asynchronous operation runs. this.cancelAsyncButton.set_Enabled(true); // Get the value from the UpDown control. numberToCompute = System.Convert.ToInt32((numericUpDown1.get_Value())); // Reset the variable for percentage tracking. highestPercentageReached = 0; // Start the asynchronous operation. backgroundWorker1.RunWorkerAsync(System.Convert.ToString (numberToCompute)); } private void cancelAsyncButton_Click(Object sender, System.EventArgs e) { // Cancel the asynchronous operation. this.backgroundWorker1.CancelAsync(); // Disable the Cancel button. cancelAsyncButton.set_Enabled(false); } // This event handler is where the actual, // potentially time-consuming work is done. private void backgroundWorker1_DoWork(Object sender, DoWorkEventArgs e) { // Get the BackgroundWorker that raised this event. BackgroundWorker worker = (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.set_Result(new Long(ComputeFibonacci(System.Convert.ToInt32 (e.get_Argument()), worker, e))); //e.Result = ComputeFibonacci((int)e.Argument, worker, e); } //backgroundWorker1_DoWork // This event handler deals with the results of the // background operation. private void backgroundWorker1_RunWorkerCompleted(Object sender, RunWorkerCompletedEventArgs e) { // First, handle the case where an exception was thrown. if (e.get_Error() != null) { MessageBox.Show(e.get_Error().get_Message()); } else { if (e.get_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.set_Text("Cancelled"); } else { // Finally, handle the case where the operation // succeeded. resultLabel.set_Text(e.get_Result().ToString()); } } // Enable the UpDown control. this.numericUpDown1.set_Enabled(true); // Enable the Start button. startAsyncButton.set_Enabled(true); // Disable the Cancel button. cancelAsyncButton.set_Enabled(false); } //backgroundWorker1_RunWorkerCompleted // This event handler updates the progress bar. private void backgroundWorker1_ProgressChanged(Object sender, ProgressChangedEventArgs e) { this.progressBar1.set_Value(e.get_ProgressPercentage()); } //backgroundWorker1_ProgressChanged // 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 new 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.get_CancellationPending()) { e.set_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; } #region Windows Form Designer generated code private void InitializeComponent() { this.numericUpDown1 = new System.Windows.Forms.NumericUpDown(); this.startAsyncButton = new System.Windows.Forms.Button(); this.cancelAsyncButton = new System.Windows.Forms.Button(); this.resultLabel = new System.Windows.Forms.Label(); this.progressBar1 = new System.Windows.Forms.ProgressBar(); this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker(); ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)). BeginInit(); this.SuspendLayout(); // // numericUpDown1 // this.numericUpDown1.set_Location(new System.Drawing.Point(16, 16)); this.numericUpDown1.set_Maximum(new System.Decimal( new int[] { 91, 0, 0, 0 })); this.numericUpDown1.set_Minimum(new System.Decimal( new int[] { 1, 0, 0, 0 })); this.numericUpDown1.set_Name("numericUpDown1"); this.numericUpDown1.set_Size(new System.Drawing.Size(80, 20)); this.numericUpDown1.set_TabIndex(0); this.numericUpDown1.set_Value(new System.Decimal( new int[] { 1, 0, 0, 0 })); // // startAsyncButton // this.startAsyncButton.set_Location(new System.Drawing.Point(16, 72)); this.startAsyncButton.set_Name("startAsyncButton"); this.startAsyncButton.set_Size(new System.Drawing.Size(120, 23)); this.startAsyncButton.set_TabIndex(1); this.startAsyncButton.set_Text("Start Async"); this.startAsyncButton.add_Click( new System.EventHandler(this.startAsyncButton_Click)); // // cancelAsyncButton // this.cancelAsyncButton.set_Enabled(false); this.cancelAsyncButton.set_Location(new System.Drawing.Point(153, 72)); this.cancelAsyncButton.set_Name("cancelAsyncButton"); this.cancelAsyncButton.set_Size(new System.Drawing.Size(119, 23)); this.cancelAsyncButton.set_TabIndex(2); this.cancelAsyncButton.set_Text("Cancel Async"); this.cancelAsyncButton.add_Click( new System.EventHandler(this.cancelAsyncButton_Click)); // // resultLabel // this.resultLabel.set_BorderStyle(System.Windows.Forms.BorderStyle.Fixed3D); this.resultLabel.set_Location(new System.Drawing.Point(112, 16)); this.resultLabel.set_Name("resultLabel"); this.resultLabel.set_Size(new System.Drawing.Size(160, 23)); this.resultLabel.set_TabIndex(3); this.resultLabel.set_Text("(no result)"); this.resultLabel.set_TextAlign(System.Drawing.ContentAlignment.MiddleCenter); // // progressBar1 // this.progressBar1.set_Location(new System.Drawing.Point(18, 48)); this.progressBar1.set_Name("progressBar1"); this.progressBar1.set_Size(new System.Drawing.Size(256, 8)); this.progressBar1.set_Step(2); this.progressBar1.set_TabIndex(4); // // backgroundWorker1 // this.backgroundWorker1.set_WorkerReportsProgress(true); this.backgroundWorker1.set_WorkerSupportsCancellation(true); // // FibonacciForm // this.set_ClientSize(new System.Drawing.Size(292, 118)); this.get_Controls().Add(this.progressBar1); this.get_Controls().Add(this.resultLabel); this.get_Controls().Add(this.cancelAsyncButton); this.get_Controls().Add(this.startAsyncButton); this.get_Controls().Add(this.numericUpDown1); this.set_Name("FibonacciForm"); this.set_Text("Fibonacci Calculator"); ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)). EndInit(); this.ResumeLayout(false); } //InitializeComponent #endregion /** @attribute STAThread() */ public static void main(String[] args) { Application.Run(new FibonacciForm()); } //main } //FibonacciForm
System.MarshalByRefObject
System.ComponentModel.Component
System.ComponentModel.BackgroundWorker
Windows 98、Windows 2000 SP4、Windows Millennium Edition、Windows Server 2003、Windows XP Media Center Edition、Windows XP Professional x64 Edition、Windows XP SP2、Windows XP Starter Edition
.NET Framework 并不是对每个平台的所有版本都提供支持。有关受支持版本的列表,请参见系统要求。
.NET Framework
受以下版本支持:2.0参考
BackgroundWorker 成员System.ComponentModel 命名空间
其他资源
如何:在后台运行操作托管线程处理的最佳做法
多线程处理 (Visual Basic)
如何:在后台下载文件
Public Class BackgroundWorker Inherits Component
Dim instance As BackgroundWorker
public class BackgroundWorker : Component
public ref class BackgroundWorker : public Component
public class BackgroundWorker extends Component
public class BackgroundWorker extends Component