为什么 CancellationTokenSource.Token.register 回调被所有请求共享?

why CancellationTokenSource.Token.register callback is shared by all request?

我试着了解这个频道的解决方案 在网络 5

我有下面的代码

      public class AppTimeout
    {
    ...

    public AppTimeout(RequestDelegate next, IOptions<ServerOptions> options)
    {
...
    }

    public async Task Invoke(HttpContext httpContext)
    {
            var cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(httpContext.RequestAborted);
            cancellationTokenSource.CancelAfter(_timeout);

            httpContext.RequestAborted = cancellationTokenSource.Token;
            var requestPath = httpContext.Request.Path;
            cancellationTokenSource.Token.Register(() =>
            {
                logger.Message("... requestPath...");
            });
        await _next(httpContext);
    }
}

请求超时后,所有请求都会触发回调

但事实并非如此,如果我替换

,回调只会在超时请求时被调用
cancellationTokenSource.Token.Register(() =>

来自

using var registration = cancellationTokenSource.Token.Register(() =>

我的问题是为什么? 你能解释一下吗?

如果没有 using 语句,cancellationTokenSourceregistration 将在请求结束后继续处于活动状态,最终您将在调用回调时获得超时 即使请求已经结束。超时不是请求超时。这是代码中错误的结果。我不确定我是否理解为什么这只会在“真正的”超时后才开始发生,但我不会浪费精力去理解它。您必须处理 registration,我相信在请求结束时也会 cancellationTokenSource(例如,通过使用 using 语句)。