我可以在BackgroundWorker上的RunWorkerCompleted()中调用RunWorkerAsync()吗?

时间:2014-11-20 19:58:32

标签: c# asynchronous backgroundworker

我有一个我已经设置的后台工作程序,我希望它在完成后可能会重新启动。也就是说,在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();
}

我无法在任何地方找到对此行为的确认。

2 个答案:

答案 0 :(得分:1)

我没有看到任何理由。根据定义它已经完成,所以IsBusy应该总是假的。而且你又回到了你所属的UI线程。

答案 1 :(得分:1)

不幸的是,文档在这个问题上并不清楚。最重要的是,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()事件处理程序调用{​​{1}}是完全安全的。

如果没有记录,实施可能会发生变化的可能性很小。但是在这个阶段,如果发生这种情况,我会感到非常惊讶。特别是在代码是开源的情况下,实现变得和其他任何东西一样都是行为规范。