如何从主线程中杀死Parallel.ForEach生成的所有线程?

enc*_*cee 4 c# multithreading kill .net-4.0 plinq

这是场景:

我有一个正在运行的Windows服务.OnStart()它设置了一个调用函数的计时器(让我们调用它ProcessEvent()).里面的代码ProcessEvent是一个关键部分,所以只有一个线程可以执行以下操作:

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

ProcessItem 可能需要很长时间.

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

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

我知道,如果我自己创建了线程,我可以将其设置isBackground为true,并且当进程死亡时它将全部被杀死,但我不会手动创建这些线程.

Bri*_*eon 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();
Run Code Online (Sandbox Code Playgroud)


spe*_*der 5

考虑的重载Parallel.ForEach是采取委托具有ParallelLoopState参数.检查正文中的标志以查看是否应继续执行,否则将其删除:

Parallel.ForEach(list, (item, pls) => { 
    if(quit)pls.Stop();
    else
        ProcessItem(item);
});
Run Code Online (Sandbox Code Playgroud)