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

Parallel.ForEach循环中Cancellation Token无法生效问题求助

解决CTRL-C无法终止Parallel.ForEach任务的问题

你的代码存在几个关键问题导致无法响应CTRL-C的取消请求,具体问题和修复方案如下:

  • 事件注册时机错误
    你在调用StartAllReaders之后才绑定Console.CancelKeyPress事件,这意味着如果用户在任务启动后立刻按下CTRL-C,事件还未生效,无法触发取消操作。必须先注册事件,再启动任务。

  • Thread.Sleep阻塞导致取消信号无法及时响应
    Thread.Sleep是不支持取消的阻塞操作,一旦进入休眠状态,即使取消令牌被触发,也要等到休眠结束才能检查取消请求。需要替换为支持取消的等待方式,让休眠过程也能响应取消信号。

  • 取消异常处理逻辑不完善
    循环内的异常捕获会吃掉所有异常,包括取消操作抛出的OperationCanceledException,导致循环无法及时退出。需要单独捕获取消异常,直接终止循环。

  • 语法错误
    代码存在几处大小写和语法问题:cts.cancel()应改为cts.Cancel(),e.cancel = true应改为e.Cancel = true,StartAllReaders(cts.token)末尾缺少分号。


修正后的代码

public static void Main(string[] args)
{
    CancellationTokenSource cts = new CancellationTokenSource();
    
    // 先注册取消事件,确保任何时候按下CTRL-C都能触发
    Console.CancelKeyPress += (s, e) =>
    {
        cts.Cancel();
        e.Cancel = true; // 阻止系统直接终止进程,让代码完成清理操作
    };
    
    StartAllReaders(cts.Token);
}

public static void StartAllReaders(CancellationToken cts)
{
    try
    {
        Parallel.ForEach(
            _readers, 
            new ParallelOptions { MaxDegreeOfParallelism = 10, CancellationToken = cts },
            (reader, state) =>
            {
                reader.Start();
                while (!cts.IsCancellationRequested)
                {
                    try
                    {
                        reader.ReadTelemetry();
                        // 用支持取消的Task.Delay替代Thread.Sleep,响应取消信号
                        Task.Delay(reader.TimeDelay, cts).Wait();
                    }
                    catch (OperationCanceledException)
                    {
                        // 捕获取消异常,直接退出循环
                        break;
                    }
                    catch (Exception ex)
                    {
                        // 记录异常日志
                        continue;
                    }
                }
                // 可选:添加reader的停止清理逻辑,比如reader.Stop()
            }); 
    }
    catch (OperationCanceledException)
    {
        Logger.Info("Readers are stopping.");
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 19:33:29