我想使用 Task.Run 以“即发即忘”的方式执行 C# 中的方法。在 Task.Run 中,每当我使用 wait 执行另一个异步方法时,HttpContext 就会变为 null。请告诉我是否有办法在 Task.Run 中运行异步方法时保留 HttpContext
示例代码:
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.Secondary.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 Upsert logic which needs to use HttpContext.Current
}
Web.config 有:
<httpRuntime maxQueryStringLength="32768" maxUrlLength="65536" targetFramework="4.5" requestValidationMode="2.0" requestPathInvalidCharacters="<,>,*,&,\,?" />
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
请让我知道如何避免此问题并在 Task.Run 中的 async/await 调用后保留 HttpContext
我想使用 Task.Run 以“即发即忘”的方式执行 C# 中的方法。
您确定这就是您想要的吗?我只是问,因为在 >90% 的情况下,人们认为他们想要一劳永逸,这实际上是他们用例的错误解决方案。
具体来说,即发即弃意味着“我不在乎此代码有时是否不运行,并且我没有收到任何有关它不运行的日志或任何类型的通知。”对于更新缓存之类的事情来说还可以,但对于更新数据库记录之类的事情来说真的很糟糕。
在Task.Run中,每当我使用await执行另一个异步方法时,HttpContext就会变为null。请告诉我是否有办法在 Task.Run 中运行异步方法时保留 HttpContext
不,没有。事实上,您根本不应该从另一个线程访问任何
HttpContext
属性或方法。换句话说,Task.Run
内的no代码应该完全访问
HttpContext
。事实上,它的一部分起作用纯粹是偶然的(如果时间不同,它可能会在生产运行时失败)。
更正确的解决方案是先从 HttpContext
中复制所需的所有内容,然后然后 启动后台工作,传入该数据副本。