如何在ASP.NET Web API 2.2中为挂起请求设置超时?
解决IIS 10中ASP.NET Web API 2.2挂起请求的问题
先说明你之前设置未生效的原因
httpRuntime executionTimeout和Server.ScriptTimeout仅针对传统ASP.NET WebForms/ASPX页面的请求管道,Web API的请求处理逻辑不在该管道范围内,因此这些配置不会生效。- 若你在应用池设置的是「闲置超时」而非「请求超时」,也无法作用于单个挂起请求。
终止挂起请求的可行方案
1. 在Web API控制器中实现请求超时逻辑
针对异步Action,利用CancellationTokenSource设置超时,强制终止长时间运行的操作:
public async Task<IHttpActionResult> GetData() { // 设置120秒超时 using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(120))) { try { // 将取消令牌传入耗时操作 var result = await LongRunningOperationAsync(cts.Token); return Ok(result); } catch (OperationCanceledException) { // 超时后返回504网关超时 return StatusCode(HttpStatusCode.GatewayTimeout); } } } private async Task<string> LongRunningOperationAsync(CancellationToken token) { // 模拟耗时操作,需确保操作支持取消令牌 await Task.Delay(TimeSpan.FromSeconds(150), token); return "完成"; }
如果是同步Action,可将同步操作包装到异步任务中,同样使用取消令牌控制超时。
2. 配置IIS应用池的请求超时
打开IIS管理器:
- 找到目标应用池 → 右键选择「高级设置」
- 展开「请求限制」 → 设置「超时(秒)」为120
- 重启应用池使配置生效
这个设置会让IIS自动终止超过指定时间的请求。
3. 临时手动终止挂起请求
- IIS管理器图形界面:
- 点击目标网站 → 右侧「管理网站」下选择「查看请求」
- 在弹出窗口中找到状态为「挂起」的请求,右键选择「终止」
- 命令行方式(appcmd):
- 以管理员身份打开命令提示符,进入
C:\Windows\System32\inetsrv目录 - 列出所有请求:
appcmd list requests - 根据请求ID终止:
appcmd stop request /REQUEST.ID:{你的请求ID}
- 以管理员身份打开命令提示符,进入
4. 自定义OWIN中间件(若使用OWIN托管Web API)
如果你的Web API通过OWIN托管,可添加全局中间件统一处理请求超时:
public class RequestTimeoutMiddleware { private readonly RequestDelegate _next; private readonly int _timeoutSeconds; public RequestTimeoutMiddleware(RequestDelegate next, int timeoutSeconds) { _next = next; _timeoutSeconds = timeoutSeconds; } public async Task Invoke(HttpContext context) { using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(_timeoutSeconds))) { var requestCancellationToken = CancellationTokenSource.CreateLinkedTokenSource(context.RequestAborted, cts.Token).Token; context.RequestAborted = requestCancellationToken; try { await _next(context); } catch (OperationCanceledException) when (cts.IsCancellationRequested) { context.Response.StatusCode = (int)HttpStatusCode.GatewayTimeout; await context.Response.WriteAsync("请求超时"); } } } } // 在Startup.cs中注册中间件 public void Configure(IApplicationBuilder app) { app.UseMiddleware<RequestTimeoutMiddleware>(120); app.UseWebApi(config); }
额外建议
终止挂起请求只是临时解决方案,建议排查请求挂起的根源:
- 检查是否存在未释放的数据库连接、未设置超时的外部API调用
- 查看应用日志、Windows事件日志中的异常信息
- 用性能分析工具(如Visual Studio Profiler)定位代码中的阻塞点
内容的提问来源于stack exchange,提问作者Must.Tek
相关产品推荐
相关产品推荐

