9

我的应用程序的用户将 HTML 类型输入到 TextBox 控件中。

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

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

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

我的 Visual Basic 代码:

子 W3CValidate(ByVal WholeDocumentText 作为字符串)

    '停止任何已经运行的验证
    If ValidationWorker.IsBusy Then
        ValidationWorker.CancelAsync()
        '等待它准备好
        While ValidationWorker.IsBusy
            '暂停百分之一秒
            System.Threading.Thread.Sleep(新时间跨度(0、0、0、0、10))
        结束时
    万一

    '开始验证
    Dim ValidationArgument As W3CValidator = New W3CValidator(WholeDocumentText)
    ValidationWorker.RunWorkerAsync(ValidationArgument)

结束子

似乎在调用了我的 BackgroundWorker 的 CancelAsync() 之后,它的 IsBusy 永远不会变为 False。它陷入了无限循环。

我究竟做错了什么?

4

3 回答 3

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();
    }
于 2009-05-27T13:10:01.673 回答
1

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.

于 2009-03-11T15:58:36.270 回答
0

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
于 2009-03-11T15:55:01.460 回答