CancelAsync () background worker not working

I am trying to undo my Backgroundworker using WorkerClass.bw.CancelAsync() . But that will not work at all.

//edit! I have posted the full code here. Let it help. Ok, I added some Msgboxes to find out if the Worker is busy and what the wiring is, that I get false while the Worker is doing something!?!?

 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 
+4
source share
2 answers

I think your problem is that you only evaluate CancellationPending once, at the beginning of your bw_DoWork method. Since there really is no way to cancel BackgroundWorker before it starts, CancellationPending will always be false and never interrupt. BackgroundWorker does not use magic to capture the program counter when calling CancelAsync .

For this to work, the main logic of your DoWork method must be implemented in such a way as to provide frequent polling of CancellationPending , so that the code knows exactly when to exit it. You will need to go from this:

 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 

Something like that:

 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 
+4
source

Here is the basic BackgroundWorker model. It looks like yours.

 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 
+3
source

Source: https://habr.com/ru/post/1484165/


All Articles