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

PLINQ中ForAll与WithCancellation组合无法中途取消查询的问题

PLINQ中WithCancellation与ForAll组合的取消行为解析

这是PLINQ的设计行为,既不是使用错误,也不是库的bug。以下是具体解析:

问题重现

复现代码

CancellationTokenSource cts = new CancellationTokenSource(1000);
cts.Token.Register(() => Console.WriteLine("--Token Canceled"));

try
{
    Enumerable.Range(1, 20)
        .AsParallel()
        .WithDegreeOfParallelism(2)
        .WithCancellation(cts.Token)
        .ForAll(x =>
        {
            Console.WriteLine($"Processing item #{x}");
            Thread.Sleep(200);
            //cts.Token.ThrowIfCancellationRequested();
        });
    Console.WriteLine($"The query was completed successfully");
}
catch (OperationCanceledException)
{
    Console.WriteLine($"The query was canceled");
}

不符合预期的输出

Processing item #1
Processing item #2
Processing item #4
Processing item #3
Processing item #5
Processing item #6
Processing item #8
Processing item #7
Processing item #10
Processing item #9
--Token Canceled
Processing item #11
Processing item #12
Processing item #13
Processing item #14
Processing item #15
Processing item #16
Processing item #17
Processing item #19
Processing item #20
Processing item #18
The query was canceled

符合预期的输出(取消注释ThrowIfCancellationRequested后)

Processing item #2
Processing item #1
Processing item #3
Processing item #4
Processing item #5
Processing item #6
Processing item #7
Processing item #8
Processing item #9
Processing item #10
--Token Canceled
The query was canceled

行为原因解析

  1. WithCancellation的作用边界:
    PLINQ的WithCancellation并非用来强制中断正在执行的委托代码,它的核心作用是:

    • 阻止PLINQ调度新的任务/处理新的项;
    • 在查询的内部检查点(比如分区分配、任务调度节点)检测取消令牌,触发查询终止流程。
      但对于已经启动的委托,PLINQ不会主动终止线程或打断正在运行的逻辑。
  2. ForAll的执行特性:
    ForAll会遍历所有分区并执行委托逻辑,一旦某个项对应的委托开始执行,PLINQ会等待该委托完成,除非委托自身主动响应取消。你看到最终抛出OperationCanceledException,是因为查询执行完毕后,PLINQ检测到令牌已处于取消状态,才抛出异常,但此时所有项都已处理完成。

正确用法

要实现中途及时取消,必须在ForAll的委托逻辑中主动检查取消令牌,在合适的时机(比如耗时操作前后)调用cts.Token.ThrowIfCancellationRequested(),这样当令牌触发取消时,正在执行的委托会立即抛出异常,PLINQ会停止调度新项,并终止整个查询流程。

内容的提问来源于stack exchange,提问作者Theodor Zoulias

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 23:25:17