Почему HttpContext.Current null после ожидания?
У меня есть следующий тестовый код WebAPI, я не использую WebAPI в производстве, но я сделал это из-за обсуждения, которое у меня было по этому вопросу: Вопрос WebAPI Async
В любом случае, здесь оскорбительный метод WebAPI:
public async Task<string> Get(int id)
{
var x = HttpContext.Current;
if (x == null)
{
// not thrown
throw new ArgumentException("HttpContext.Current is null");
}
await Task.Run(() => { Task.Delay(500); id = 3; });
x = HttpContext.Current;
if (x == null)
{
// thrown
throw new ArgumentException("HttpContext.Current is null");
}
return "value";
}
Я полагал, что второе исключение ожидается, потому что, когда завершается await
, он, скорее всего, будет в другом потоке, где HttpContext.Current
как поточно-статическая переменная больше не будет соответствовать соответствующему значению. Теперь, основываясь на контексте синхронизации, на самом деле его можно заставить вернуться в тот же поток после ожидания, но я не делаю ничего необычного в своем тесте. Это простое, наивное использование await
.
В комментариях в другом вопросе мне сказали, что HttpContext.Current
следует решить после ожидания. Там еще один комментарий по этому вопросу указывает на то же самое. Так что же верно? Должен ли он разрешаться? Я думаю, нет, но я хочу получить авторитетный ответ на это, потому что async
и await
достаточно новые, что я не могу найти ничего определенного.
TL; DR: HttpContext.Current
потенциально null
после await
?
Ответы
Ответ 1
Пожалуйста, убедитесь, что вы пишете приложение ASP.NET 4.5 и настроите 4.5. async
и await
имеют поведение undefined на ASP.NET, если вы не работаете в версии 4.5 и используете новый "контекстный" контекст синхронизации.
В частности, это означает, что вы должны:
- Установите
httpRuntime.targetFramework
в 4.5
или
- В вашем
appSettings
установите aspnet:UseTaskFriendlySynchronizationContext
в true
.
Дополнительная информация доступна здесь.
Ответ 2
Поскольку @StephenCleary правильно указал, вам это нужно в вашем web.config:
<httpRuntime targetFramework="4.5" />
Когда я впервые устранил эту проблему, я сделал поиск решения для всего выше, подтвердил, что он присутствует во всех моих веб-проектах и быстро отклонил его как виновника. В конце концов мне пришло в голову рассмотреть эти результаты поиска в полном контексте:
<!--
For a description of web.config changes for .NET 4.5 see http://go.microsoft.com/fwlink/?LinkId=235367.
The following attributes can be set on the <httpRuntime> tag.
<system.Web>
<httpRuntime targetFramework="4.5" />
</system.Web>
-->
Doh.
Урок. Если вы обновляете веб-проект до версии 4.5, вам все равно нужно установить эту настройку вручную.
Ответ 3
Я ошибаюсь в своем тестировании, или есть какой-то элемент web.config, который мне не хватает здесь это приведет к правильному разрешению HttpContext.Current после ждут?
Ваш тест не является дефектным, и HttpContext.Current не должен быть нулевым после ожидания, потому что в ASP.NET Web API, когда вы его ожидаете, это гарантирует, что код, следующий за этим ожиданием, передается правильный HttpContext, который присутствовал до жду.