如何正确取消永远工作的后台工作者?

时间:2014-07-17 16:43:37

标签: vb.net backgroundworker

伙计们,我有一个vb.net应用程序,当按下按钮时我会启动后台工作程序。 BGW永远在Do循环中工作,除非我按下另一个按钮,在这种情况下它应该停止,执行其他一些工作然后BGW重新启动。

到目前为止,基于在线研究,我有两个版本的代码,虽然这两个版本都有不同的结果。到目前为止的代码是:

Dim autoEvent As New AutoResetEvent(False)
Private Sub StartWorkerButton_Click () Handles StartWorkerButton.Click
    MyWorker.WorkerSupportsCancellation = True
    MyWorker.WorkerReportsProgress = True
    MyWorker.RunWorker.Asunc()
End Sub

Private Sub MyWorker_ProgressChanged () Handles MyWorker.Progresschanged
    'Update some text boxes text string here based on data from the BGW work
End Sub

Private Sub StopThenRestartButton_Click Handles StopThenRestartButton.Click
    If MyWorker.IsBusy Then
        MyWorker.CancelAsync()
        autoEvent.WaitOne()
        ' Do some work here
        MyWorker.RunWorkerAsync() ' Restart BGW - But this fails!
    Else
        ' Do same work here but without stopping and restarting BGW
    End If
Exit Sub

Private Sub MyWorker_DoWork () Handles MyWorker.DoWork
    Do While 1
        If MyWorker.CancellationPending = True
            e.Cancel = True
            autoEvent.set
            Exit Sub
        Else
            ' Do some task work over and over again
            'ReportProgress() here as well
        End If
End Sub

无论我使用哪种方式,似乎执行都可以请求取消,设置事件,但之后不会重新启动BGW,因为它似乎仍然正在运行。克。

1 个答案:

答案 0 :(得分:0)

您应该允许主线程上的事件处理,并等待工作程序完成。实际上你不需要autoEvent

Private Sub StopThenRestartButton_Click() Handles StopThenRestartButton.Click

    If MyWorker.IsBusy Then
        MyWorker.CancelAsync()
        autoEvent.WaitOne()
        While MyWorker.IsBusy
            'Process the events
            Application.DoEvents()
        End While
        ' Do some work here
        MyWorker.RunWorkerAsync() ' Restart BGW
    Else
        ' Do same work here but without stopping and restarting BGW
    End If

End Sub

以下是没有autoEvent

的代码
Private Sub StartWorkerButton_Click() Handles StartWorkerButton.Click
    MyWorker.WorkerSupportsCancellation = True
    MyWorker.WorkerReportsProgress = True
    MyWorker.RunWorkerAsync()
End Sub

Private Sub MyWorker_ProgressChanged() Handles MyWorker.ProgressChanged
    'Update some text boxes text string here based on data from the BGW work
End Sub

Private Sub MyWorker_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles MyWorker.RunWorkerCompleted
    Console.WriteLine("RunWorkerCompleted Called")

End Sub


Private Sub StopThenRestartButton_Click() Handles StopThenRestartButton.Click
    If MyWorker.IsBusy Then
        MyWorker.CancelAsync()
        While MyWorker.IsBusy
            Application.DoEvents()
        End While
        Console.WriteLine("Worker Finished. Going to restart")

        ' Do some work here
        MyWorker.RunWorkerAsync() ' Restart BGW 
    Else
        ' Do same work here but without stopping and restarting BGW
    End If
End Sub

Private Sub MyWorker_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles MyWorker.DoWork
    Do While 1
        If MyWorker.CancellationPending = True Then
            e.Cancel = True
            Exit Do ' Exit Sub also works here, if you have nothing to do after the loop
        Else
            ' Do some task work over and over again
            'ReportProgress() here as well
        End If
    Loop
End Sub