我知道控制器的HttpContext
属性是异步安全的。当您在异步操作内部调用它时,它总是返回当前操作的上下文。
但我很好奇这是如何实现的
如果我理解正确的话,它不能使用线程本地存储技术来实现。因为在await
之后,异步方法可以在池中的另一个线程上恢复。或者,另一方面,当异步方法是"异步"时;"睡眠";,池中的同一个线程可以执行另一个异步方法。
从后台线程访问HttpContext:
从后台线程访问HttpContext
HttpContext
不是线程安全的。在处理请求之外读取或写入HttpContext
的属性可能会导致NullReferenceException。
存储HttpContext
实例并将其传递或使用IHttpContextAccessor
接口可能会因此给您带来麻烦。
控制器应该收集必要的请求信息以传递给其他组件/服务,并使用该调用的结果来贡献响应。
正如@Damien_The_Unbeliever所建议的,HttpContext
属性确实使用了AsyncLocal
,如本文所述:
namespace Microsoft.AspNetCore.Http
{
public class HttpContextAccessor : IHttpContextAccessor
{
private static AsyncLocal<HttpContext> _httpContextCurrent = new AsyncLocal<HttpContext>();
public HttpContext HttpContext
{
get
{
return _httpContextCurrent.Value;
}
set
{
_httpContextCurrent.Value = value;
}
}
}
}