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

FastEndpoints是否支持为所有端点设置全局请求超时?

FastEndpoints 请求超时与 CancellationToken 触发问题解答

CancellationToken 触发的常见原因

你观察到的 CancellationToken 触发,最常见的原因确实是客户端主动断开连接(比如用户关闭浏览器、APP退出或网络中断)。除此之外,也可能是请求处理流程中主动调用了取消逻辑,或者后续中间件/业务代码触发了取消,但客户端断开是最普遍的场景。

FastEndpoints 的请求超时支持

FastEndpoints 本身没有内置的请求超时功能,但它基于 ASP.NET Core 构建,因此可以直接利用 ASP.NET Core 的原生机制来实现请求超时,包括全局配置和单个端点配置。

全局请求超时的实现方式

以下是两种常用的全局超时配置方案:

1. Kestrel 层面全局超时

直接在 Kestrel 服务器配置中设置请求超时,超过指定时间后服务器会主动断开连接,触发 CancellationToken:

builder.WebHost.ConfigureKestrel(options =>
{
    // 设置全局请求超时为30秒
    options.Limits.RequestTimeout = TimeSpan.FromSeconds(30);
});

这种方式是最底层的超时控制,所有经过 Kestrel 的请求都会生效。

2. 自定义中间件实现全局超时

如果需要自定义超时后的响应内容(比如返回特定的错误JSON),可以编写一个全局中间件来包裹请求:

// 先定义超时配置选项
public class RequestTimeoutOptions
{
    public TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds(30);
}

// 自定义超时中间件
public class RequestTimeoutMiddleware
{
    private readonly RequestDelegate _next;
    private readonly TimeSpan _timeout;

    public RequestTimeoutMiddleware(RequestDelegate next, IOptions<RequestTimeoutOptions> options)
    {
        _next = next;
        _timeout = options.Value.Timeout;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        // 关联原有请求取消令牌和超时令牌
        using var timeoutCts = new CancellationTokenSource(_timeout);
        using var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(context.RequestAborted, timeoutCts.Token);
        context.RequestAborted = linkedCts.Token;

        try
        {
            await _next(context);
        }
        catch (OperationCanceledException) when (timeoutCts.IsCancellationRequested)
        {
            // 超时触发时返回408状态码和自定义响应
            context.Response.StatusCode = StatusCodes.Status408RequestTimeout;
            context.Response.ContentType = "application/json";
            await context.Response.WriteAsync("{\"error\":\"请求超时,请稍后重试\"}");
        }
    }
}

// 注册配置和中间件
builder.Services.Configure<RequestTimeoutOptions>(options =>
{
    options.Timeout = TimeSpan.FromSeconds(30);
});
// 注意中间件要放在FastEndpoints中间件之前
builder.UseMiddleware<RequestTimeoutMiddleware>();
builder.UseFastEndpoints();

单个端点的超时控制

如果只需要给特定端点设置超时,可以在端点的处理逻辑中创建关联的取消令牌:

public class OrderProcessingEndpoint : Endpoint<OrderRequest, OrderResponse>
{
    public override void Configure()
    {
        Post("/api/orders/process");
        AllowAnonymous();
    }

    public override async Task HandleAsync(OrderRequest req, CancellationToken ct)
    {
        // 设置当前端点的超时为20秒,关联原有取消令牌
        using var timeoutCts = CancellationTokenSource.CreateLinkedTokenSource(ct);
        timeoutCts.CancelAfter(TimeSpan.FromSeconds(20));

        try
        {
            // 将timeoutCts.Token传入耗时操作
            var result = await OrderService.ProcessAsync(req.OrderId, timeoutCts.Token);
            await SendAsync(result);
        }
        catch (OperationCanceledException) when (timeoutCts.IsCancellationRequested)
        {
            await SendAsync(new OrderResponse { Success = false, Message = "订单处理超时" }, 408);
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 11:42:50