我已经设置了一名后台工作人员,希望在完成后可以重新启动。也就是说,在DoWork()完成之后,如果结果不成功,我想再次从RunWorkerCompleted()处理程序中调用RunWorkerAsync()。当我进入RunWorkerCompleted()时,可以确定IsBusy = false吗?

例如:

void myThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if ((e.Error == null) && !e.Cancelled && (bool)e.Result)
        // do stuff
    else
        myThread.RunWorkerAsync();
}


我似乎在任何地方都找不到这种行为的确认。

最佳答案

不幸的是,有关该问题的文档尚不清楚。最重要的是,IsBusy属性的代码示例实际上非常糟糕,因为它在属性上旋转等待并在循环中调用Application.DoEvents()

就是说,正如其他人所建议的那样,最明智的设计是仅在异步工作程序实际运行时才将标志设置为true。即DoWork事件处理程序返回时,应将其设置回false。实际上,如果人们查看the implementation,就会看到以下内容:

private void AsyncOperationCompleted(object arg)
{
    isRunning = false;
    cancellationPending = false;
    OnRunWorkerCompleted((RunWorkerCompletedEventArgs)arg);
}

public bool IsBusy
{
    get
    {
        return isRunning;
    }
}


此处的isRunning标志是IsBusy属性返回的内容,也是RunWorkerAsync()检查是否应引发异常的内容。从这里可以看到,该实现在引发false事件之前将其设置回RunWorkerCompleted

因此,是的……从RunWorkerAsync()事件处理程序中调用RunWorkerCompleted是绝对安全的。

没有对此进行记录,则实现更改的可能性很小。但是在现阶段,如果发生这种情况,我会感到非常惊讶。尤其是在开源代码的情况下,实现与其他行为一样成为行为规范。

10-08 08:37