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

.NET 7/8中API请求的CancellationToken失效问题排查求助

问题分析与解决方案

你的代码存在两个核心问题,导致无法正确检测并响应请求取消:

  1. 异步操作未绑定取消令牌
    你调用await Task.Delay(1000)时没有传入cancellationToken,这意味着即便请求被取消,延迟操作仍会执行完1秒才进入下一次循环检查,无法及时响应取消信号。

  2. 未处理框架自动抛出的取消异常
    当客户端主动中断请求(比如Postman点击取消),ASP.NET Core会触发cancellationToken取消,并在后续代码使用已取消令牌时抛出OperationCanceledException。这个异常默认会被框架捕获并返回500状态码,而非你期望的499。

修改后的代码

using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.MapGet("/long-running-request", async (CancellationToken cancellationToken) =>
    {
        var randomId = Guid.NewGuid();
        var results = new List<string>();

        try
        {
            for (int i = 0; i < 100; i++)
            {
                // 提前检查取消状态
                if (cancellationToken.IsCancellationRequested)
                    return Results.StatusCode(499);

                // 将取消令牌传入异步操作,确保取消时立即终止延迟
                await Task.Delay(1000, cancellationToken);
                var result = $"{randomId} - Result {i}";
                Console.WriteLine(result);
                results.Add(result);
            }

            return Results.Ok(results);
        }
        catch (OperationCanceledException)
        {
            // 捕获框架抛出的取消异常,返回499状态码
            return Results.StatusCode(499);
        }
    })
    .WithName("GetAllData")
    .WithOpenApi();

app.Run();

补充说明

  • 所有异步I/O操作(数据库查询、HTTP请求、延迟等)都必须传入CancellationToken,才能在请求取消时立即终止操作,避免资源浪费。
  • 499是Nginx定义的「客户端主动关闭连接」状态码,ASP.NET Core无内置该状态码,需手动通过Results.StatusCode(499)返回。
  • 测试时,在Postman发送请求后点击「Cancel」按钮,即可立即触发取消逻辑并返回499。

内容的提问来源于stack exchange,提问作者Łukasz Zapała

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 22:55:04