You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

为何ASP.NET异步请求常忽略httpRuntime的executionTimeout配置?

为什么ASP.NET异步请求会忽略<httpRuntime>里的executionTimeout配置?

这个问题本质是ASP.NET同步与异步请求处理机制的核心差异导致的,我来给你拆解清楚:

核心原因:executionTimeout是为同步请求设计的

<httpRuntime executionTimeout="120" />这个配置专门针对同步请求的超时控制——它监控的是ASP.NET分配给请求的初始线程的执行时长。但在异步请求场景下:

  • 当代码执行到await关键字时,ASP.NET会把当前线程释放回线程池,等待异步操作完成后再重新分配线程继续处理请求。
  • 此时executionTimeout的监控对象(初始线程)已经不再处理请求了,自然不会触发超时判定。

而你配置里的requestValidationMode="2.0"targetFramework="4.7"是会正常作用于异步请求的,只有executionTimeout对异步场景完全无效。

异步请求该怎么控制超时?

先提一句:你的示例代码里c变量一直没递增,会无限循环跑下去,这在生产环境绝对要避免!针对异步请求的超时,推荐这两种方式:

方式1:用CancellationTokenSource手动设置超时

修改代码加入超时令牌,主动控制请求执行时长:

public async Task<HttpResponseMessage> ImAlive()
{
    // 设置120秒超时,和你原本的executionTimeout配置对应
    using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(120));
    int c = 0;
    try
    {
        do
        {
            // 传入取消令牌,超时后会抛出OperationCanceledException
            await Task.Delay(1000, cts.Token);
            ILogger.Log("ImAlive!");
            c++; // 必须递增变量,否则会无限循环
        } while (c < 10000);
        return Request.CreateResponse(HttpStatusCode.OK);
    }
    catch (OperationCanceledException)
    {
        return Request.CreateResponse(HttpStatusCode.RequestTimeout);
    }
}

方式2:利用Web API内置的请求取消令牌

ASP.NET Web API会自动为每个请求生成CancellationToken,客户端断开连接或服务器触发超时(注意这是专门的异步请求超时配置,和executionTimeout无关)时,令牌会被取消:

public async Task<HttpResponseMessage> ImAlive(CancellationToken cancellationToken)
{
    int c = 0;
    try
    {
        do
        {
            await Task.Delay(1000, cancellationToken);
            ILogger.Log("ImAlive!");
            c++;
        } while (c < 10000);
        return Request.CreateResponse(HttpStatusCode.OK);
    }
    catch (OperationCanceledException)
    {
        return Request.CreateResponse(HttpStatusCode.RequestTimeout);
    }
}

额外提醒

如果是IIS托管的站点,还可以在IIS层面设置连接超时(站点高级设置里),但这是针对TCP连接的超时,和请求执行超时不是一回事,别搞混了。

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

火山引擎 最新活动