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

用于限制API执行时间的TimeoutAttribute实现异常排查

问题排查与修正方案

你的TimeoutAttribute未能按预期工作,核心问题有以下几点:

1. 时间单位错误

构造函数中错误地将毫秒参数传给了TimeSpan.FromSeconds,导致超时时间被放大1000倍。例如传入5000(期望5秒超时),实际会设置5000秒(约1小时23分)的超时,完全无法触发预期的超时逻辑。

修正:将TimeSpan.FromSeconds改为TimeSpan.FromMilliseconds。

2. 拦截时机错误

你重写的OnActionExecutingAsync是Action执行前的钩子方法,基类的base.OnActionExecutingAsync是空实现,当前代码的超时控制只作用于这个空方法,完全没有覆盖到实际的API接口业务逻辑执行环节,因此超时逻辑根本不会影响Action的执行。

3. 未正确包裹Action执行过程

要实现Action的超时控制,必须将Action的执行逻辑纳入超时监控范围内,而不是仅给过滤器的前置方法加超时。


修正后的完整代码示例

public class TimeoutAttribute : ActionFilterAttribute
{
    private readonly TimeSpan _timeout;

    public TimeoutAttribute(int timeoutInMilliseconds)
    {
        // 修正时间单位:使用毫秒转换为TimeSpan
        _timeout = TimeSpan.FromMilliseconds(timeoutInMilliseconds);
    }

    public override async Task OnActionExecutingAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
    {
        using (var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
        {
            cts.CancelAfter(_timeout);

            try
            {
                // 手动触发Action执行,并将超时令牌传入,控制执行过程
                var actionResult = await actionContext.ActionDescriptor.ExecuteAsync(
                    actionContext.ControllerContext, 
                    actionContext.ActionArguments, 
                    cts.Token);
                
                // 生成成功响应
                actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.OK, actionResult);
            }
            catch (OperationCanceledException)
            {
                // 触发超时返回408
                actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.RequestTimeout, ApiErrorMessages.RequestTimeout);
            }
            catch (Exception ex)
            {
                // 处理其他异常
                actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.Message);
            }
        }
    }
}

额外注意事项

  • 如果你的Action内部包含异步操作,需要确保这些异步方法正确响应传入的CancellationToken,否则即使触发超时,后台任务可能仍会继续执行。
  • 若要避免后台任务泄漏,可以在超时触发后,确保所有异步操作都能被正确取消。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 07:19:57