HurstOlds
HurstOlds

Reputation: 51

vb.net background worker cancel not working

I'm having an issue where BackgroundWorker.CancelAsync() isn't working. I have WorkerSupportsCancellation set to TRUE. I am also polling BackgroundWorker1.CancellationPending in DoWork. Here is sample code of what I am trying to achieve. I have background worker looping through a time stamp and assigning a value to Measurement variable. I have a subroutine that queries the last reported Measurement variable and writes to listbox. After 5 loops I send BackgroundWorker.CancelAsync(). I can see the cancellation is pending, but it doesn't actually cancel the background worker. Is this a race condition?

Public Class Form1

Dim Measurement As String
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click

    BackgroundWorker1.RunWorkerAsync()
    Delay(0.5)

    For x = 1 To 5
        ListBox1.Items.Add(Measurement)
        ListBox1.TopIndex = ListBox1.Items.Count - 1
        TextBox1.Text = BackgroundWorker1.CancellationPending
        Delay(1)
    Next

    BackgroundWorker1.CancelAsync()

    TextBox1.Text = BackgroundWorker1.CancellationPending
    ListBox1.Items.Add("Cancel Pend: " & BackgroundWorker1.CancellationPending)
    Delay(5)
    ListBox1.Items.Add("Busy: " & BackgroundWorker1.IsBusy)

End Sub

Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork

    If BackgroundWorker1.CancellationPending = True Then
        e.Cancel = True
        BackgroundWorker1.Dispose()
        Exit Sub
    Else
        Do
            Measurement = Now()
        Loop
    End If

End Sub

End Class

Upvotes: 0

Views: 1161

Answers (1)

Steve
Steve

Reputation: 216243

You just need to move the check for the cancellation inside the Do...Loop otherwise it will be tested only at the start of the DoWork event handler and never after that

Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork

    If BackgroundWorker1.CancellationPending = True Then
        e.Cancel = True
        BackgroundWorker1.Dispose()
    Else
        Do
          If BackgroundWorker1.CancellationPending = True Then
            e.Cancel = True
            BackgroundWorker1.Dispose()
            Exit Do
          Else 
             Measurement = Now()
          End If
        Loop
    End if
End Sub

Upvotes: 1

Related Questions