Vb.net Backgroundworker CancelAsync()赢了';行不通
我正试图用Vb.net Backgroundworker CancelAsync()赢了';行不通,vb.net,backgroundworker,Vb.net,Backgroundworker,我正试图用WorkerClass.bw.CancelAsync()取消我的Backgroundworker。但它根本不起作用 //编辑!我在这里发布了完整的代码。希望这会有帮助。 好的,我添加了一些MSGBoxe,以了解工作人员是否仍然很忙,而有线的事情是,当工作人员在做事情时,我会得到一个false Public Class Form1 Private Sub btn_start_click(ByVal sender As System.Object, ByVal e As System.E
WorkerClass.bw.CancelAsync()
取消我的Backgroundworker。但它根本不起作用
//编辑!我在这里发布了完整的代码。希望这会有帮助。
好的,我添加了一些MSGBoxe,以了解工作人员是否仍然很忙,而有线的事情是,当工作人员在做事情时,我会得到一个false
强>
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
下面是后台工作人员的基本模型。这就是你的样子
Dim WithEvents worker As New System.ComponentModel.BackgroundWorker
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'start
If Not worker.IsBusy Then
worker.WorkerReportsProgress = True
worker.WorkerSupportsCancellation = True
worker.RunWorkerAsync()
End If
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
'cancel
If worker.IsBusy AndAlso worker.WorkerSupportsCancellation Then
worker.CancelAsync()
End If
End Sub
Private Sub foo_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles worker.DoWork
For x As Integer = 1 To 15
If worker.CancellationPending Then
e.Cancel = True
Exit For
End If
worker.ReportProgress(x)
Threading.Thread.Sleep(1000)
Next
End Sub
Private Sub foo_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles worker.ProgressChanged
Label1.Text = e.ProgressPercentage.ToString
End Sub
Private Sub foo_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles worker.RunWorkerCompleted
If e.Cancelled Then
Label1.Text = "canceled"
ElseIf Not IsNothing(e.Error) Then
Label1.Text = "error " & e.Error.Message
Else
Label1.Text = "done"
End If
End Sub
我认为您的问题在于,在
bw\u-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
您是否设置了
WorkerClass.bw.workerSupportsScanCellation=True
?否则它不会取消任何东西。你能把整个backgroundworker代码放进去吗?我放了。你能再看一遍吗?)Allready添加了这个部分。取消支票不是问题。它很好用。我的问题是,工作人员告诉我它不忙?你能在按钮点击处理程序中输入一个,并确认CancelAsync
甚至被调用吗?不完全正确,但大多数情况下这应该与我的代码相同。所有的工作,尤其是CancelAsync()
好的,我试着用你的来编辑我的,我总是得到worker.IsBusy的布尔值false。不知道为什么,因为工人在工作?!在后台工作程序实际启动并将属性更新为True
之前,从调用RunWorkerAsync开始可能会有延迟。生成新线程并开始执行代码需要时间。您在下一行中选中的IsBusy
(再次,一次且仅一次)可能发生在任何一行完成之前。如果你任意延迟(比如3000毫秒),那么它可能会工作。好的,你是对的。但这仍然没有解决我的问题。我还是不能取消那个工人的工作。即使在下一个语句中使用了一个简单的