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

查看:343
本文介绍了如何等待一个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 it to be cancelled
   }
}

一个人怎么可以等待做一个BackgroundWorker?

How can one wait for a BackgroundWorker to be done?

在过去人们曾尝试:

   while (!_worker.IsDone)
   {
      Sleep(100);
   }

不过这是一个僵局,因为 IsBusy 不清除的 RunWorkerCompleted 处理事件后,直到在该事件不会得到处理,直到应用程序进入空闲状态。该应用程序将不会进入空闲状态,直到工作人员完成。 (另外,这是一个繁忙的循环 - 而这是多么恶心的)

But this is a deadlock, since the IsBusy is not cleared until after the RunWorkerCompleted event is handled, and that event won'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 - and how disgusting is that)

还有人建议加kludging成:

Others have add suggested kludging it into:

   while (!_worker.IsDone)
   {
      Application.DoEvents();
   }

与该问题是,为 Application.DoEvents()导致目前的消息队列中进行处理,这会导致重新entrantcy问题(.NET不重-entrant)。

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

我希望使用一些解决方案,涉及事件同步对象,其中code 等待作为一个事件 - 该工人的 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.

推荐答案

如果我理解你的要求吧,你可以做这样的事情(code没有测试过,但显示的总体思路):

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天全站免登陆