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

未调用cts.Cancel(),Task为何抛出TaskCanceledException异常?

为什么没调用cts.Cancel()却抛出TaskCanceledException?

核心原因出在你用的TaskContinuationOptions.OnlyOnCanceled选项上,和CancellationTokenSource本身没关系:

  • 你的主任务(StartNew内的逻辑)抛出了普通异常,最终会进入**Faulted(故障)**状态。
  • 你给主任务绑定的延续任务指定了OnlyOnCanceled,这个选项的意思是只有当主任务被取消时,延续任务才会被执行。但现在主任务是故障状态,不满足触发条件,所以这个延续任务根本不会被调度执行,直接进入**Canceled(取消)**状态。
  • 当你await这个已取消的延续任务时,就会自动抛出TaskCanceledException——这就是报错的来源。

怎么解决?

如果你想处理主任务的异常,别用OnlyOnCanceled,换成OnlyOnFaulted;或者更推荐用async/await原生的try-catch直接捕获主任务异常,比ContinueWith更直观:

方案1:直接捕获主任务异常

var cts = new CancellationTokenSource();
try
{
    await Task.Factory.StartNew(() =>
    {
        throw new Exception("测试异常");                      
    }, cts.Token);
}
catch (Exception ex)
{
    // 在这里处理主任务抛出的异常
    Console.WriteLine($"捕获到异常:{ex.Message}");
}

方案2:用ContinueWith分别处理不同状态

如果一定要用ContinueWith,可以给不同任务状态绑定对应的延续逻辑:

var cts = new CancellationTokenSource();
var mainTask = Task.Factory.StartNew(() =>
{
    throw new Exception("测试异常");                      
}, cts.Token);

// 处理主任务故障的情况
await mainTask.ContinueWith(t =>
{
    Console.WriteLine($"主任务异常:{t.Exception.InnerException.Message}");
}, TaskContinuationOptions.OnlyOnFaulted);

// 处理主任务被取消的情况(如果有需要)
await mainTask.ContinueWith(t =>
{
    Console.WriteLine("主任务已取消");
}, TaskContinuationOptions.OnlyOnCanceled);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 02:00:34