ThrowIfCancellationRequested似乎没有抛出任何异常
本文关键字:任何 异常 ThrowIfCancellationRequested | 更新日期: 2023-09-27 17:51:02
我有以下代码:
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
包含的元素很少。当我按下'c'时,所有Compute
方法都已启动。
当我按下'c'时,不会抛出异常。每个Compute
方法继续执行,直到正常结束。
当我按下'c'时,我想停止/杀死所有剩余的Compute
方法
取消不是这样工作的。它不像调用Thread.Abort()
来立即终止线程。
对于序列中的每个元素,代码执行:
- 调用
- 等待完成
- 写到控制台完成
- 检查是否请求取消,如果是则抛出
OperationCanceledException
。
Compute()
方法为了取消一些任务,你需要将CancellationToken
传递给被调用的方法。
也许,值得将长时间运行的计算组织为一个循环,并检查是否在每一步都请求取消,以便尽快停止它。
例如,在Compute()
方法中,您可以执行这样的检查:
private void Compute(CancellationToken ct)
{
while (true)
{
ComputeNextStep();
ct.ThrowIfCancellationRequested();
}
}
观察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();