自定义请求超时中间件触发的TaskCanceledException无法被IExceptionHandler捕获的问题求助
自定义请求超时中间件触发的TaskCanceledException无法被IExceptionHandler捕获的问题求助
我正在尝试在C#中为请求实现通用超时机制。我知道有请求超时中间件,但它无法传递异常(因为中间件内部会自行处理异常),这样我们常规的问题中间件就没法把异常包装成ProblemDetails来处理。所以我先写了一个简单的版本:
public class CancelInTimeMiddleware : IMiddleware { // 更深入理解为什么无法轻易终止所有请求 public async Task InvokeAsync(HttpContext context, RequestDelegate next) { var originalCt = context.RequestAborted; using (var timoutTS = CancellationTokenSource.CreateLinkedTokenSource(originalCt)) { timoutTS.CancelAfter(10000); // 10秒后自动取消 context.RequestAborted = timoutTS.Token; await next(context); } } }
然后我写了一个简单的端点:
public static async Task<IResult> GetTimer(int delaySeconds, CancellationToken cancellationToken) { logger.LogInformation("Entering the wait!"); await Task.Delay(delaySeconds * 1000, cancellationToken); // catch (TaskCanceledException) -> 我也想处理那些忘了捕获该异常的情况 return Results.Json(new { Message = "Waiting is done" }); }
于是我添加了一个简单的IExceptionHandler:
class SimpleExceptionHandler : IExceptionHandler { public async ValueTask<bool> TryHandleAsync( HttpContext httpContext, Exception exception, CancellationToken cancellationToken) { // 自定义响应对象 var error = new { message = exception.Message }; await httpContext.Response.WriteAsJsonAsync(error, cancellationToken); return true; } }
注册方式如下:
builder.Services.AddProblemDetails(); builder.Services.AddExceptionHandler<SimpleExceptionHandler>(); builder.Services.AddSingleton<CancelInTimeMiddleware>(); var app = builder.Build(); app.UseExceptionHandler(_ => { }); app.UseMiddleware<CancelInTimeMiddleware>(); app.MapGet("wait/{delaySeconds:int}", TestEndPointsImplementations.GetTimer); app.Run();
现在其他我主动抛出的异常都能被正常处理,但超时触发的取消操作却不行。是不是因为CancellationToken触发后,请求管道就直接停止了?
备注:内容来源于stack exchange,提问作者Sunib
相关产品推荐
相关产品推荐

