Search code examples
vb.netvisual-studio-2010visual-studiobackgroundworker

Background Worker thread not ending on cancellation


I am having a little issue, I finally figured out how to add a background worker to my application now my only problem is it does not end the thread, or atleast not fast enough when I am clicking my cancel button. I must be doing something wrong. I would like for it to abort the thread as soon as the button is clicked. Is this feasable? My thread is by no means extensive.

I am going to post some examples of the way I am doing it.

    Public Sub New()
    InitializeComponent()

    bw.WorkerReportsProgress = True
    bw.WorkerSupportsCancellation = True
    AddHandler bw.DoWork, AddressOf bw_DoWork
    ' AddHandler bw.ProgressChanged, AddressOf bw_ProgressChanged
    AddHandler bw.RunWorkerCompleted, AddressOf bw_RunWorkerCompleted
End Sub

My DoWork Event

    Private Sub bw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)

    If bw.CancellationPending = True Then
        e.Cancel = True
        WorkEventRunning = False

    Else

        CheckForIllegalCrossThreadCalls = False
        Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
        'my long winded event
         ' more of my long winded event.

   End if

My Cancel button Code

    Private Sub ToolStripButton2_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripButton2.Click
    'Stop
    If bw.WorkerSupportsCancellation = True Then
        WorkEventRunning = False
        bw.CancelAsync()
        bw.Dispose()

    End If

And my WorkCompleted

     Private Sub bw_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
    If e.Cancelled = True Then
        'canceled
        WorkEventRunning = False
    ElseIf e.Error IsNot Nothing Then
        MsgBox(e.Error.Message)
    Else
        'done
    End If
End Sub

Solution

  • In the DoWork event, test for CancellationPending inside the long winded event. Supposing that this long procedure contains a For-Loop or a ForEach then at every loop test for CancellationPending

    For example:

    Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
    Dim x as Integer
    For x = 0 to 1000000
        If worker.CancellationPending = True Then 
            e.Cancel = True 
            Return 
        Else 
           .... ' Execute the works for this loop
        End If
    Next
    

    The same test could be done inside the RunWorkerCompleted event because CancelAsync() sets the internal value for the CancellationPending property. See this question to look at the inner workings of CancelAsync()