如何等待 BackgroundWorker 取消? [英] How to wait for a BackgroundWorker to cancel?

查看:33
本文介绍了如何等待 BackgroundWorker 取消?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑一个为你做事的对象的假设方法:

Consider a hypothetical method of an object that does stuff for you:

public class DoesStuff
{
    BackgroundWorker _worker = new BackgroundWorker();

    ...

    public void CancelDoingStuff()
    {
        _worker.CancelAsync();

        //todo: Figure out a way to wait for BackgroundWorker to be cancelled.
    }
}

如何等待 BackgroundWorker 完成?

How can one wait for a BackgroundWorker to be done?

过去人们曾尝试过:

while (_worker.IsBusy)
{
    Sleep(100);
}

但是这个僵局,因为IsBusy 直到 RunWorkerCompleted 事件被处理后才会被清除,并且在应用程序空闲之前无法处理该事件.在工作程序完成之前,应用程序不会闲置.(另外,这是一个繁忙的循环 - 恶心.)

But this deadlocks, because IsBusy is not cleared until after the RunWorkerCompleted event is handled, and that event can't get handled until the application goes idle. The application won't go idle until the worker is done. (Plus, it's a busy loop - disgusting.)

其他人建议将其添加到:

Others have add suggested kludging it into:

while (_worker.IsBusy)
{
    Application.DoEvents();
}

问题在于 Application.DoEvents() 导致当前队列中的消息被处理,从而导致重入问题(.NET 不可重入).

The problem with that is that is Application.DoEvents() causes messages currently in the queue to be processed, which cause re-entrancy problems (.NET isn't re-entrant).

我希望使用一些涉及事件同步对象的解决方案,其中代码等待事件 - 工作人员的 RunWorkerCompleted 事件处理程序设置.类似的东西:

I would hope to use some solution involving Event synchronization objects, where the code waits for an event - that the worker's RunWorkerCompleted event handlers sets. Something like:

Event _workerDoneEvent = new WaitHandle();

public void CancelDoingStuff()
{
    _worker.CancelAsync();
    _workerDoneEvent.WaitOne();
}

private void RunWorkerCompletedEventHandler(sender object, RunWorkerCompletedEventArgs e)
{
    _workerDoneEvent.SetEvent();
}

但我又回到了僵局:在应用程序空闲之前事件处理程序无法运行,并且应用程序不会因为它在等待事件而空闲.

But I'm back to the deadlock: the event handler can't run until the application goes idle, and the application won't go idle because it's waiting for an Event.

那么你怎么能等待一个BackgroundWorker完成呢?

So how can you wait for an BackgroundWorker to finish?

更新人们似乎对这个问题感到困惑.他们似乎认为我会将 BackgroundWorker 用作:

Update People seem to be confused by this question. They seem to think that I will be using the BackgroundWorker as:

BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += MyWork;
worker.RunWorkerAsync();
WaitForWorkerToFinish(worker);

那是不是它,那不是我正在做的不是,也不是这里要问的.如果是这样,那么使用后台工作人员就没有意义了.

That is not it, that is not what I'm doing, and that is not what is being asked here. If that were the case, there would be no point in using a background worker.

推荐答案

如果我理解你的要求,你可以做这样的事情(代码未经测试,但显示了总体思路):

If I understand your requirement right, you could do something like this (code not tested, but shows the general idea):

private BackgroundWorker worker = new BackgroundWorker();
private AutoResetEvent _resetEvent = new AutoResetEvent(false);

public Form1()
{
    InitializeComponent();

    worker.DoWork += worker_DoWork;
}

public void Cancel()
{
    worker.CancelAsync();
    _resetEvent.WaitOne(); // will block until _resetEvent.Set() call made
}

void worker_DoWork(object sender, DoWorkEventArgs e)
{
    while(!e.Cancel)
    {
        // do something
    }

    _resetEvent.Set(); // signal that worker is done
}

这篇关于如何等待 BackgroundWorker 取消?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆