如何正确取消并重新启动BackgroundWorker进程?

Zac*_*son 9 .net multithreading backgroundworker

我的应用程序的用户将HTML类型转换为TextBox控件.

我希望我的应用程序在后台验证他们的输入.

因为我不想敲定验证服务,所以我尝试在每次验证之前建立一秒钟的延迟.

但是,我似乎无法正确中断已经运行的BackgroundWorker进程.

我的Visual Basic代码:

Sub W3CValidate(ByVal WholeDocumentText As String)

    'stop any already-running validation
    If ValidationWorker.IsBusy Then
        ValidationWorker.CancelAsync()
        'wait for it to become ready
        While ValidationWorker.IsBusy
            'pause for one-hundredth of a second
            System.Threading.Thread.Sleep(New TimeSpan(0, 0, 0, 0, 10))
        End While
    End If

    'start validation
    Dim ValidationArgument As W3CValidator = New W3CValidator(WholeDocumentText)
    ValidationWorker.RunWorkerAsync(ValidationArgument)

End Sub

看来在调用我的BackgroundWorker的CancelAsync()之后,它的IsBusy永远不会变为False.它陷入无限循环.

我究竟做错了什么?

小智 8

尝试这样的事情:

bool restartWorker = false;

    void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
                    // add other code here
        if (e.Cancelled && restartWorker)
        {
            restartWorker = false;
            backgroundWorker1.RunWorkerAsync();
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        if (backgroundWorker1.IsBusy)
        {
            restartWorker = true;
            backgroundWorker1.CancelAsync();
        }
        else
            backgroundWorker1.RunWorkerAsync();
    }
Run Code Online (Sandbox Code Playgroud)


Zac*_*son 0

我在这篇文章中找到了答案:

BackgroundWorker 关闭和可重写任务作者:Patrick Smacchia

我修改了他的代码:

私有 _ValidationArgument 作为 W3CValidator

Sub W3CValidate(ByVal WholeDocumentText 作为字符串)
    如果 _ValidationArgument 不是什么,那么
        _ValidationArgument = 新 W3CValidator(WholeDocumentText)
        退出子程序
    万一
    如果不是 ValidationWorker.IsBusy 那么
        ValidationWorker.RunWorkerAsync(新W3CValidator(WholeDocumentText))
        退出子程序
    万一
    _ValidationArgument = 新 W3CValidator(WholeDocumentText)
    ValidationWorker.CancelAsync()
    Dim TimerRetryUntilWorkerNotBusy 作为新的 Windows.Threading.DispatcherTimer
    AddHandler TimerRetryUntilWorkerNotBusy.Tick、AddressOf WorkTicker
    TimerRetryUntilWorkerNotBusy.Interval = New TimeSpan(1) '100 纳秒
    TimerRetryUntilWorkerNotBusy.Start()
结束子

Sub WorkTicker(ByVal 发送者作为对象,ByVal e 作为 System.EventArgs)
    如果 ValidationWorker.IsBusy 那么
        退出子程序
    万一
    DirectCast(发送者, Windows.Threading.DispatcherTimer).Stop()
    ValidationWorker.RunWorkerAsync(_ValidationArgument)
    _ValidationArgument = 无
结束子