【问题标题】:Canceling Threads取消线程
【发布时间】:2010-03-05 09:05:29
【问题描述】:

我有一个使用 20 个线程的应用程序。这是一个使用线程发送邮件的电子邮件客户端。

目前线程是在主线程中创建的。但是我想知道,如果我想取消整个操作怎么办?我能看到的唯一方法是杀死主线程......从而结束程序。

我是否必须创建一个线程来封装邮件线程,以便我可以终止封装线程?

顺便说一句,我目前正在使用 BackgroundWorker,它是一个 WF 应用程序。

【问题讨论】:

  • 你有 20 个 Backgroundworker 线程或使用它来启动其他线程

标签: c#


【解决方案1】:

如果您使用的是BackgroundWorker,那么您已经拥有取消操作所需的所有基础架构。只需在BackgroundWorker 上将WorkerSupportsCancellation 设置为true,并在要取消时调用worker 的CancelAsync 方法。

显然,您必须编写工作代码来兑现取消操作。您可以通过检查BackgroundWorkerCancellationPending 属性来做到这一点。

MSDN 有一个example 使用此属性。


注意 - 我对BackgroundWorker 和 20 个线程的组合有点困惑; BackgroundWorker 只使用一个线程。您是否正在拆分 20 BackgroundWorkers?如果是这样,您如何确保它们得到妥善处理?如果您在 Winforms 应用程序中需要如此多的并发性,那么最好使用异步委托或线程池。

如果您正在创建实际线程,实现取消标志的一种常见方法是使用ManualResetEvent。如果您以零超时等待此事件,它将充当线程安全状态标志。一个示例用法是:

ManualResetEvent cancelEvent = new ManualResetEvent(false);
for (int i = 0; i < 20; i++)
{
    ThreadPool.QueueUserWorkItem(s =>
    {
        // Do some work
        if (cancelEvent.WaitOne(0, true))
            return;
        // Do some more work
        // etc.
    });
}

然后在稍后的某个时间,如果你写cancelEvent.Set(),每个工人都会在达到状态检查后立即停止工作。

【讨论】:

  • 是的,但这不会只是取消当前线程吗?每个线程都设置为从公司数据库中发送一组选定的电子邮件。所以如果我取消那个线程,其他 19 人应该还活着吧?
猜你喜欢
  • 1970-01-01
  • 2013-10-23
  • 2011-05-12
  • 2020-05-23
  • 2010-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-19
相关资源
最近更新 更多