为什么 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
语句,cancellationTokenSource
和 registration
将在请求结束后继续处于活动状态,最终您将在调用回调时获得超时 即使请求已经结束。超时不是请求超时。这是代码中错误的结果。我不确定我是否理解为什么这只会在“真正的”超时后才开始发生,但我不会浪费精力去理解它。您必须处理 registration
,我相信在请求结束时也会 cancellationTokenSource
(例如,通过使用 using
语句)。
我试着了解这个频道的解决方案
我有下面的代码
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
语句,cancellationTokenSource
和 registration
将在请求结束后继续处于活动状态,最终您将在调用回调时获得超时 即使请求已经结束。超时不是请求超时。这是代码中错误的结果。我不确定我是否理解为什么这只会在“真正的”超时后才开始发生,但我不会浪费精力去理解它。您必须处理 registration
,我相信在请求结束时也会 cancellationTokenSource
(例如,通过使用 using
语句)。