我试图用WorkerClass.bw.CancelAsync()取消我的Backgroundworker.但它根本不起作用. //编辑!我在这里发布了完整的代码.愿这会有所帮助. 好吧,我添加了一些Msgbox,以了解工作者是否仍然很忙并且有
//编辑!我在这里发布了完整的代码.愿这会有所帮助.
好吧,我添加了一些Msgbox,以了解工作者是否仍然很忙并且有线的事情是,当工人正在做事时我得到了一个错误!?!?
Public Class Form1 Private Sub btn_start_click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_start.Click Dim WorkerClass As New BGWClass WorkerClass.bw.WorkerSupportsCancellation = True WorkerClass.bw.WorkerReportsProgress = True If btn_start.Text = "Start" Then btn_start.Image = My.Resources.Resources.gem_remove btn_add_addy.Enabled = False btn_start.Text = "Stop" WorkerClass.Start() WorkerClass.bw.RunWorkerAsync() MsgBox(WorkerClass.bw.IsBusy & " " & WorkerClass.bw.WorkerSupportsCancellation) Else btn_start.Image = My.Resources.Resources.error_fuck btn_add_addy.Enabled = True btn_start.Enabled = False MsgBox(WorkerClass.bw.IsBusy & " " & WorkerClass.bw.WorkerSupportsCancellation) WorkerClass.bw.CancelAsync() End If End Sub End Class Public Class BGWClass Public bw As BackgroundWorker = New BackgroundWorker Sub Start() AddHandler bw.DoWork, AddressOf bw_DoWork AddHandler bw.ProgressChanged, AddressOf bw_ProgressChanged AddHandler bw.RunWorkerCompleted, AddressOf bw_RunWorkerCompleted End Sub Private Sub bw_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) For x As Integer = 1 To 15 If bw.CancellationPending Then e.Cancel = True Exit Sub End If bw.ReportProgress(x) Threading.Thread.Sleep(1000) Next End Sub Private Sub bw_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Dim myObject As Object = e.UserState Form1.Prgs_error.Text = "- Error: " + e.ProgressPercentage.ToString End Sub Private Sub bw_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) '... End Sub End Class我认为你的问题是你只是在你的bw_DoWork方法开始时评估一次CancellationPending.由于在启动之前没有真正取消BackgroundWorker的方法,因此CancellationPending将始终为false并且永远不会中断工作.当您调用CancelAsync时,BackgroundWorker不会使用某种魔法来接管程序计数器.
为了使其工作,DoWork方法的核心逻辑必须以允许频繁轮询CancellationPending的方式实现,以便代码准确地知道何时退出它正在做的事情.你需要从这个:
Private Sub bw_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) If bw.CancellationPending = True Then e.Cancel = True Else 'do stuff here End If End Sub
对于更像这样的事情:
Private Sub bw_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Dim workIsCompleted As Boolean = False While (Not bw.CancellationPending) AndAlso (Not workIsCompleted) Then ' Do stuff here, but incrementally so that the while loop can ' periodically check to see if CancelAsync has been called. ' Also, be sure to set workIsCompleted = True when the work is done. ' Otherwise, you will just spin forever until someone cancels it ' (Which may or may not be a bad thing, depending on your requirements) End While End Sub