以下是该方案:
我有正在运行的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,当进程死亡时它们都会被杀死但我不会手动创建这些线程。
答案 0 :(得分:8)
使用CancellationToken结构。有关详细信息,请阅读this和this。
// 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();
答案 1 :(得分:5)
查看带有Parallel.ForEach参数的委托的ParallelLoopState重载。检查正文中的标志,看看是否应继续执行,否则将其删除:
Parallel.ForEach(list, (item, pls) => {
if(quit)pls.Stop();
else
ProcessItem(item);
});