我有以下代码:
CancellationTokenSource cts = new CancellationTokenSource();
ParallelOptions po = new ParallelOptions();
po.CancellationToken = cts.Token;
Task.Factory.StartNew(() =>
{
if (Console.ReadKey().KeyChar == 'c')
cts.Cancel();
Console.WriteLine("press any key to exit");
});
Parallel.ForEach(list, po, (algo) =>
{
algo.Compute(); // this compute lasts 1 minute
Console.WriteLine("this job is finished");
po.CancellationToken.ThrowIfCancellationRequested();
});
list
包含很少的元素。
当我按下'
Compute
方法都已启动。
当我按下' c'时,不会抛出任何异常。每个Compute
方法都会继续执行,直到正常结束。
当我按下“c'”时,我想停止/删除所有剩余的Compute
方法。
答案 0 :(得分:2)
取消并不是那样的。它不像调用Thread.Abort()
来立即终止线程。
对于代码中序列中的每个元素:
Compute()
方法OperationCanceledException
。要取消某项任务,您需要将CancellationToken
传递给被叫方法
也许,值得将长时间运行的计算作为一个循环进行组织,并检查是否在每一步都要求取消以便尽快停止它。
例如,在您的Compute()
方法中,您可以执行以下检查:
private void Compute(CancellationToken ct)
{
while (true)
{
ComputeNextStep();
ct.ThrowIfCancellationRequested();
}
}
答案 1 :(得分:0)
使用po.CancellationToken.IsCancellationRequested
观察取消,并使用ParallelLoopState.Stop
停止Parallel.ForEach
:
void Compute(CancellationToken token, ParallelLoopState loopState)
{
bool more = true;
while (more)
{
if (token.IsCancellationRequested)
{
// stop Parallel.ForEach ASAP
loopState.Stop();
return;
}
// do the calc step
}
}
// ...
CancellationTokenSource cts = new CancellationTokenSource();
ParallelOptions po = new ParallelOptions();
po.CancellationToken = cts.Token;
Task.Factory.StartNew(() =>
{
if (Console.ReadKey().KeyChar == 'c')
cts.Cancel();
Console.WriteLine("press any key to exit");
});
Parallel.ForEach(list, po, (algo, loopState) =>
{
algo.Compute(po.CancellationToken, loopState); // this compute lasts 1 minute
Console.WriteLine("this job is finished");
});
// observe the cancellation again and throw after Parallel.ForEach
po.CancellationToken.ThrowIfCancellationRequested();