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

发布于 2024-07-14 19:49:17 字数 871 浏览 8 评论 0原文

我的应用程序的用户将 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。 它陷入了无限循环。

我究竟做错了什么?

Users of my application type HTML into a TextBox control.

I want my application to validate their input in the background.

Because I don't want to hammer the validation service, I've tried to build in a one-second delay before each validation.

However, I don't seem to be able to correctly interrupt an already-running BackgroundWorker process.

My Visual Basic code:

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

It seems that after calling my BackgroundWorker's CancelAsync(), its IsBusy never becomes False. It gets stuck in an infinite loop.

What am I doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

榆西 2024-07-21 19:49:17

尝试这样的事情:

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();
    }

Try something like this:

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();
    }
め七分饶幸 2024-07-21 19:49:17

在后台工作进程循环中,您需要检查
backgroundWorkerPageProcess.CancellationPending

并相应退出。 然后,一旦它存在,您的 while 循环 isBusy 就应该被相应地标记。

更新:设置 Cancel = true 后,您是否从该方法中返回? 在这里吐痰
更新 2:您已在后台工作程序上将 WorkerSupportsCancellation 标志设置为 true 吗?
另外,在工人完成的方法中,如果 e.Cancelled 则返回...更多吐球

更新 3:
经过我自己的一些检查和编译后,似乎该死的东西永远不会在相同的方法中摆脱 isbusy 。
- 一个选项是在忙碌时禁用该按钮,并让另一个选项取消,仅供用户重新单击验证。
-或者在您的工作人员完成的方法上 if(e.Cancelled) 使用适当的文本调用您的验证方法......

不过,无论哪种方式都是失败的。 很抱歉在这里帮不上什么忙。

In your background worker process loop you need to check for
backgroundWorkerPageProcess.CancellationPending

and exit accordingly. Then once it exists your while loop isBusy should be flagged accordingly.

Update: After you set Cancel = true are you returning out of the method? spitballing here
Update 2: You have the WorkerSupportsCancellation flag set to true on the backgroundworker?
Also in worker completed method return out if e.Cancelled.... more spitballs

Update 3:
after some checking and compilation of my own it appears the damn thing never gets out of isbusy within the same method.
-One option is to disable the button while busy and have another to cancel, only for the user to reclick the validation.
-Or on your worker completed method if(e.Cancelled) call your validation method with appropriate text....

either way is kind of bust though. Sorry to not be of much help here.

ㄟ。诗瑗 2024-07-21 19:49:17

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

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

我改编了他的代码:

Private _ValidationArgument As W3CValidator

Sub W3CValidate(ByVal WholeDocumentText As String)
    If _ValidationArgument IsNot Nothing Then
        _ValidationArgument = New W3CValidator(WholeDocumentText)
        Exit Sub
    End If
    If Not ValidationWorker.IsBusy Then
        ValidationWorker.RunWorkerAsync(New W3CValidator(WholeDocumentText))
        Exit Sub
    End If
    _ValidationArgument = New W3CValidator(WholeDocumentText)
    ValidationWorker.CancelAsync()
    Dim TimerRetryUntilWorkerNotBusy As New Windows.Threading.DispatcherTimer
    AddHandler TimerRetryUntilWorkerNotBusy.Tick, AddressOf WorkTicker
    TimerRetryUntilWorkerNotBusy.Interval = New TimeSpan(1) '100 nanoseconds
    TimerRetryUntilWorkerNotBusy.Start()
End Sub

Sub WorkTicker(ByVal sender As Object, ByVal e As System.EventArgs)
    If ValidationWorker.IsBusy Then
        Exit Sub
    End If
    DirectCast(sender, Windows.Threading.DispatcherTimer).Stop()
    ValidationWorker.RunWorkerAsync(_ValidationArgument)
    _ValidationArgument = Nothing
End Sub

I found the answer in this article:

BackgroundWorker Closure and Overridable Task by Patrick Smacchia

I've adapted his code:

Private _ValidationArgument As W3CValidator

Sub W3CValidate(ByVal WholeDocumentText As String)
    If _ValidationArgument IsNot Nothing Then
        _ValidationArgument = New W3CValidator(WholeDocumentText)
        Exit Sub
    End If
    If Not ValidationWorker.IsBusy Then
        ValidationWorker.RunWorkerAsync(New W3CValidator(WholeDocumentText))
        Exit Sub
    End If
    _ValidationArgument = New W3CValidator(WholeDocumentText)
    ValidationWorker.CancelAsync()
    Dim TimerRetryUntilWorkerNotBusy As New Windows.Threading.DispatcherTimer
    AddHandler TimerRetryUntilWorkerNotBusy.Tick, AddressOf WorkTicker
    TimerRetryUntilWorkerNotBusy.Interval = New TimeSpan(1) '100 nanoseconds
    TimerRetryUntilWorkerNotBusy.Start()
End Sub

Sub WorkTicker(ByVal sender As Object, ByVal e As System.EventArgs)
    If ValidationWorker.IsBusy Then
        Exit Sub
    End If
    DirectCast(sender, Windows.Threading.DispatcherTimer).Stop()
    ValidationWorker.RunWorkerAsync(_ValidationArgument)
    _ValidationArgument = Nothing
End Sub
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文