无法阻止BackgroundWorker

时间:2016-05-20 15:01:04

标签: c# multithreading backgroundworker

我知道这个问题已多次发布,但这种情况有所不同。所以假设我正在执行一个需要迭代几个项目(数据库行)的方法,这需要很多时间。
现在在我的BackgroundWorker我需要在某些情况下停止同步,特别是当用户按下按钮时。我在_DoWork事件中所做的是:

private void worker_DoWork(object sender, DoWorkEventArgs e)
{
    while (!worker.CancellationPending)
    {
        LongOperation();
    }
}

现在问题在于,当我呼叫worker.CancelAsync()LongOperation()继续执行,但不应该!因为while的条件为CancellationPending。我在网上看到这个解决方案是thread-safe,所以也许我做错了什么?

2 个答案:

答案 0 :(得分:4)

您只需要以下结构

private void runButton_Click(object sender, EventArgs e)
{
    worker=new BackgroundWorker();

    worker.WorkerSupportsCancellation=true;
    worker.RunWorkerCompleted+=Bk_RunWorkerCompleted;
    worker.DoWork+=Bk_DoWork;
    worker.RunWorkerAsync();
}

private void cancelButton_Click(object sender, EventArgs e)
{
    worker.CancelAsync();
}

void ReallyReallyLongOperation(BackgroundWorker worker)
{
    ...within a loop
    if(worker.CancellationPending) 
    {
        return;
    }
}

private void Bk_DoWork(object sender, DoWorkEventArgs e)
{
    ReallyReallyLongOperation(worker);
    if(worker.CancellationPending)
    {
        e.Cancel = true;
    }
}

private void Bk_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if(!e.Cancelled)
    {
        ...
    }
}

答案 1 :(得分:1)

  

LongOperation()继续执行,但不应该!因为while的条件为CancellationPending

不,它应该继续执行!理解while检查是完全错误的。它不会检查取消的每一秒,它仅在开始LongOperation之前进行检查!

因此,在这种情况下,您唯一可以做的就是检查worker.CancellationPending内部内的LongOperation属性,而不是// we send this ['hello', 'world'] // Firebase databases store this {0: 'hello', 1: 'world'} 方法。