Я хочу выполнить метод на С# с подходом «Выстрелил и забыл», используя 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 после вызовов async/await в Task.Run.





Я хочу выполнить метод на С# с подходом «Выстрелил и забыл», используя Task.Run.
Вы уверены, что это то, что вы хотите? Я просто спрашиваю, потому что в> 90% случаев, когда люди думают, что хотят «выстрелил и забыл», это на самом деле неправильное решение для их варианта использования.
В частности, «выстрелил и забыл» означает: «Меня не волнует, если этот код иногда не запускается, и я не получаю никаких журналов или уведомлений любого рода о том, что он не запускается». Это нормально для таких вещей, как обновление кэшей, но очень плохо для таких вещей, как обновление записей базы данных.
В Task.Run всякий раз, когда я выполняю другой асинхронный метод с ожиданием, HttpContext становится нулевым. Пожалуйста, дайте мне знать, есть ли способ сохранить HttpContext при выполнении асинхронных методов внутри Task.Run.
Нет, нет. Фактически, вы вообще не должны получать доступ к каким-либо HttpContext свойствам или методам из другого потока. Другими словами, никакой код внутри Task.Run вообще не должен обращаться к HttpContext. Тот факт, что часть этого работает, является чисто случайным (и он может дать сбой во время выполнения в производстве, если время отличается).
Более правильное решение — сначала скопировать все, что вам нужно, из HttpContext, а затем начать фоновую работу, передав эту копию данных.
Если вы получаете нуль, то соединение никогда не завершалось, и вы получаете исключение тайм-аута. Невозможно сохранить HttpContext, если нет ответа по тайм-ауту.