【IT168技术文档】
许多经常执行的操作可能需要很长的执行时间。例如:
图像下载
Web 服务调用
文件下载和上载(包括点对点应用程序)
复杂的本地计算
数据库事务
本地磁盘访问(相对于内存访问来说其速度很慢)
例子里是微软本身的例子和我的例子,一个窗体两个 BackgroundWorker,两个可以一起运行啊
第一个是求斐波纳契数
http://msdn.microsoft.com/zh-cn/library/system.componentmodel.backgroundworker%28VS.80%29.aspx
第二个是不断地向richtextbox里添加行,类似于日志,完成一个后在里面显示一下。
微软的东西都封装了哎。例子外有几个问题:
(1)“您必须非常小心,确保在 DoWork 事件处理程序中不操作任何用户界面对象。而应该通过 ProgressChanged 和 RunWorkerCompleted 事件与用户界面进行通信。”
但是测试发现,放在ProgressChangedUI还是没有响应的。所以只能放在 DoWork里
(2) 如果出现Cross-thread operation not valid: Control 'RichTextBox1' accessed from a thread other than the thread it was created on.
在窗体的构造方法里加上这个即可。
Control.CheckForIllegalCrossThreadCalls = False
.vb
Imports System.ComponentModel Public Class TestBackGroundWorkClass TestBackGroundWork Private lStrValue = String.Empty Private numberToCompute As Integer = 0 Private highestPercentageReached As Integer = 0 Sub New()Sub New() ' This call is required by the Windows Form Designer. InitializeComponent() Me.BackgroundWorker1.WorkerSupportsCancellation = True ' Add any initialization after the InitializeComponent() call. 'Control.CheckForIllegalCrossThreadCalls = False End Sub msdn 例子#Region "msdn 例子" Private Sub Button1_Click()Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 'befor backgroundwork ' Me.TextBox2.Text = mFnGetNum(CInt(TextBox1.Text)) TextBox2.Text = String.Empty numberToCompute = CInt(TextBox1.Text) highestPercentageReached = 0 BackgroundWorker1.RunWorkerAsync(numberToCompute) Me.Button1.Enabled = False While Me.BackgroundWorker1.IsBusy ' Keep UI messages moving, so the form remains ' responsive during the asynchronous operation. Application.DoEvents() End While Me.Button1.Enabled = True End Sub Private Sub Button2_Click()Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Me.BackgroundWorker1.CancelAsync() End Sub Public Function mFnGetNum()Function mFnGetNum(ByVal Num As Integer, _ ByVal worker As BackgroundWorker, _ ByVal e As DoWorkEventArgs) As Long Dim result As Long = 0 If worker.CancellationPending Then e.Cancel = True Else If Num < 2 Then result = 1 Else result = mFnGetNum(Num - 1, worker, e) + _ mFnGetNum(Num - 2, worker, e) End If ' Report progress as a percentage of the total task. Dim percentComplete As Integer = _ CSng(Num) / CSng(numberToCompute) * 100 If percentComplete > highestPercentageReached Then highestPercentageReached = percentComplete worker.ReportProgress(percentComplete) End If End If Return result End Function Public Function mFnGetNum()Function mFnGetNum(ByVal Num As Integer) As Long Dim result As Long = 0 If Num < 2 Then result = 1 Else result = mFnGetNum(Num - 1) + mFnGetNum(Num - 2) End If Return result End Function Private Sub BackgroundWorker1_DoWork()Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork Dim worker As System.ComponentModel.BackgroundWorker = CType(sender, System.ComponentModel.BackgroundWorker) e.Result = mFnGetNum(e.Argument, worker, e) End Sub Private Sub BackgroundWorker1_ProgressChanged()Sub BackgroundWorker1_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged Me.ProgressBar1.Value = e.ProgressPercentage End Sub Private Sub BackgroundWorker1_RunWorkerCompleted()Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted 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. TextBox2.Text = "Canceled" Else ' Finally, handle the case where the operation succeeded. TextBox2.Text = e.Result.ToString() End If End Sub #End Region