ThrowIfCancellationRequested似乎没有抛出任何exception

我有以下代码:

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’时,不会抛出任何exception。 每个Compute方法都会继续执行,直到正常结束。

当我按’c’时,我想停止/杀死所有剩余的Compute方法。

取消不是那样的。 它不像调用Thread.Abort()来立即终止线程。

对于代码中序列中的每个元素:

  1. 调用Compute()方法
  2. 等到完成
  3. 写入控制台关于完成
  4. 检查是否请求取消,如果是,则抛出OperationCanceledException

要取消某些任务,您需要将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();