4

这是场景:

我有一个正在运行的 Windows 服务。OnStart()它设置了一个将调用函数的计时器(我们称之为ProcessEvent())。里面的代码ProcessEvent是临界区,所以只有一个线程可以做以下事情:

private void ProcessEvent(object sender, ElapsedEventArgs e)
{
    lock(lockObj)
    {
        string[] list = GetList();
        Parallel.ForEach(list, item => { ProcessItem(item) });
    }
}

ProcessItem可能需要很长时间。

现在,当服务停止时,我OnStop()目前只是停止并处理计时器。但是我注意到,即使服务停止后,仍有线程仍在运行ProcessItem()

那么我怎样才能杀死该程序产生的所有正在运行的线程(主要是由 产生的线程,Parallel.ForEach但也包括任何等待锁定的线程ProcessEvent)?

我知道如果我自己创建了线程,我可以设置isBackground为 true 并且当进程终止时它都会被杀死,但我不会手动创建这些线程。

4

2 回答 2

8

使用CancellationToken结构。阅读内容和内容以获取更多信息。

// Setup the cancellation mechanism.
var cts = new CancellationTokenSource();
var po = new ParallelOptions();
po.CancellationToken = cts.Token;

// Run the enumerator in parallel.
Parallel.ForEach(list, po, 
  (item) =>
  {
    ProcessItem(item);
    po.CancellationToken.ThrowIfCancellationRequested();
  });

// Call Cancel to make Parallel.ForEach throw.
// Obviously this must done from another thread.
cts.Cancel();
于 2011-05-19T13:06:06.487 回答
5

查看带有ParallelLoopState参数的委托的Parallel.ForEach的重载。检查主体中的标志以查看是否应继续执行,否则将其终止:

Parallel.ForEach(list, (item, pls) => { 
    if(quit)pls.Stop();
    else
        ProcessItem(item);
});
于 2011-05-19T01:06:23.810 回答