You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 6的Parallel.ForEachAsync为何需要两个取消令牌参数?

Parallel.ForEachAsync 双取消令牌的作用与差异

两个令牌的各自作用

  • 方法入参位置的CancellationToken(你代码里的token变量):属于全局循环控制令牌
    它的作用范围覆盖整个并行循环的全生命周期:
    1. 循环启动前如果该令牌已经被标记为取消,Parallel.ForEachAsync会直接抛出OperationCanceledException,不会启动任何迭代任务
    2. 循环运行过程中该令牌被取消时,会立即终止后续未分配的迭代调度,同时通知所有正在运行的迭代需要终止
  • 委托入参位置的CancellationToken(你代码里的t变量):属于迭代关联令牌
    这个令牌是Parallel.ForEachAsync内部生成的,和当前迭代的生命周期绑定,它的取消触发条件包含两种场景:
    1. 你传入的全局循环控制令牌被取消
    2. 任意一个迭代抛出未处理的异常,触发并行循环的整体终止流程

二者的核心差异

二者最值得注意的差异是取消触发场景的覆盖范围不同:

  1. 全局控制令牌只会响应你主动调用cts.Cancel()的操作,如果并行循环是因为某个迭代抛出异常触发终止,全局令牌的IsCancellationRequested属性仍然为false,但委托内的迭代令牌会被标记为取消
  2. 迭代内做取消状态检查时,优先使用委托传入的迭代令牌,不要只依赖自己定义的全局令牌,否则会漏掉异常触发的终止信号,导致迭代任务无法及时退出

示例代码说明

你提供的示例逻辑可以正常终止循环,仅存在一个冗余点:循环外的token.ThrowIfCancellationRequested()可以直接删除,Parallel.ForEachAsync本身会在启动前自动检查你传入的全局令牌状态,不需要手动调用检查。

内容的提问来源于stack exchange,提问作者Vic F

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 06:54:00