提问人:user2760913 提问时间:8/11/2023 最后编辑:user2760913 更新时间:8/12/2023 访问量:123
在 Task.Run 中等待/异步后将 HttpContext.Current 获取为 null
Getting HttpContext.Current as null after await/async in Task.Run
问:
我想在 C# 中使用“即发即弃”方法执行一个方法。每当我用 执行另一个方法时,就会变成 。请让我知道是否有办法在运行方法时保留。Task.Run
Task.Run
async
await
HttpContext
null
HttpContext
async
Task.Run
示例代码:
public virtual async Task AddAsync(TModel item)
{
// Copy HttpContext to use in Task.Run
var httpRequest = HttpContext.Current?.Request;
var httpResponse = HttpContext.Current?.Response;
var contextItems = HttpContext.Current?.Items;
Task.Run(async () =>
{
var taskContext = new HttpContext(httpRequest, httpResponse);
if (contextItems?.Keys != null)
{
foreach (var key in contextItems.Keys)
{
taskContext.Items.Add(key, contextItems[key]);
}
}
HttpContext.Current = taskContext; // Context gets copied here correctly.
try
{
await this.InsertAsync(item);
}
catch (Exception ex)
{
// Log error
}
});
}
public virtual async Task InsertAsync(TModel item)
{
var contextBeforeAwait = HttpContext.Current; // This is not null
await this.DoAsyncWork();
var contextAfterAwait = HttpContext.Current; // Context here becomes null
// Remaining Insert logic which needs to use HttpContext.Current
}
Web.config 具有:
<httpRuntime targetFramework="4.5" />
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
请让我知道如何避免此问题并在 .HttpContext
Task.Run
答:
4赞
Stephen Cleary
8/11/2023
#1
我想使用 Task.Run 在 C# 中以“即发即弃”方法执行方法。
你确定这就是你想要的吗?我只是问,因为在 >90% 的人们认为他们想要即发即弃的情况下,这实际上是他们用例的错误解决方案。
具体来说,即发即弃意味着“我不在乎这段代码有时是否没有运行,我也不会收到任何关于它没有运行的日志或通知。对于更新缓存之类的事情来说,这是可以的,但对于更新数据库记录之类的事情来说,这真的很糟糕。
在 Task.Run 中,每当我使用 await 执行另一个异步方法时,HttpContext 就会变为 null。请让我知道是否有办法在 Task.Run 中运行异步方法时保留 HttpContext
不,没有。事实上,你根本不应该从另一个线程访问任何属性或方法。换句话说,a 内部的任何代码都不应该访问。它的一部分工作的事实纯粹是偶然的(如果时间不同,它可能会在生产运行时失败)。HttpContext
Task.Run
HttpContext
更合适的解决方案是先复制您需要的所有内容,然后开始后台工作,传入该数据副本。HttpContext
评论