Fla*_*ien 6 .net-core asp.net-core asp.net-core-1.1
在ASP.NET Core中,我IHttpContextAccessor用来访问current HttpContext。HttpContextAccessor使用AsyncLocal<T>。
在一种情况下,我尝试Task从请求中启动a ,该请求应在请求结束后继续运行(长时间运行,后台任务),并且尝试将其与当前执行上下文分离以便IHttpContextAccessor返回null(否则我正在访问无效的HttpContext)。
我尝试了Task.Run,Thread.Start但是每次情况下,上下文似乎都会继承并IHttpContextAccessor返回旧的上下文,无论我尝试执行什么(有时甚至是来自其他请求的上下文)。
如何启动AsyncLocal状态为干净的任务,然后IHttpContextAccessor返回null?
小智 8
迟到的答案,但可能对其他人有用。您可以通过在提交任务时抑制 ExecutionContext 流来做到这一点:
ExecutionContext.SuppressFlow();
var task = Task.Run(async () => {
await LongRunningMethodAsync();
});
ExecutionContext.RestoreFlow();
Run Code Online (Sandbox Code Playgroud)
或更好:
using (ExecutionContext.SuppressFlow()) {
var task = Task.Run(async () => {
await LongRunningMethodAsync();
});
}
Run Code Online (Sandbox Code Playgroud)
这将防止在提交的任务中捕获 ExecutionContext。因此,它将具有“干净”的 AsyncLocal 状态。
如上所述,如果它是 CPU 密集型后台工作,我不会在 ASP.net 中执行此操作。
您可以等待长时间运行的任务并在await 中HttpContext设置为null 。对于任务之外的所有代码来说都是安全的。
[Fact]
public async Task AsyncLocalTest()
{
_accessor = new HttpContextAccessor();
_accessor.HttpContext = new DefaultHttpContext();
await LongRunningTaskAsync();
Assert.True(_accessor.HttpContext != null);
}
private async Task LongRunningTaskAsync()
{
_accessor.HttpContext = null;
}
Run Code Online (Sandbox Code Playgroud)
你可以运行一个单独的线程,这并不重要。
Task.Run(async () => await LongRunningTaskAsync());
Run Code Online (Sandbox Code Playgroud)
只需让任务等待清理HttpContext任务的异步上下文即可。
| 归档时间: |
|
| 查看次数: |
819 次 |
| 最近记录: |