Почему HttpContext.Current имеет значение null после ожидания?
У меня есть следующий тестовый код WebAPI, я 9X_await не использую WebAPI в производстве, но сделал 9X_visual-c# это из-за обсуждения этого вопроса: WebAPI Async question
В любом 9X_asp.net случае, вот оскорбительный метод WebAPI:
public async Task 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"; }
До 9X_async-ctp сих пор я полагал, что ожидается второе 9X_await исключение, потому что, когда await
завершится, оно, скорее 9X_visual-c# всего, будет в другом потоке, где HttpContext.Current
как статическая 9X_asp.net-website переменная потока больше не будет разрешаться 9X_asp.net до соответствующего значения. Теперь, исходя 9X_asp-net из контекста синхронизации, его можно заставить 9X_c-sharp вернуться к тому же потоку после ожидания, но 9X_c#-language я не делаю ничего особенного в своем тесте. Это 9X_async-await простое, наивное использование await
.
В комментариях 9X_c# к другому вопросу мне сказали, что HttpContext.Current
должен 9X_.net-async-await разрешиться после ожидания. Есть даже еще 9X_c# один комментарий по этому вопросу, указывающий 9X_asp.net-website на то же самое. Так что правда? Должен ли 9X_async-await он разрешиться? Думаю, нет, но мне нужен 9X_async-await авторитетный ответ по этому поводу, потому 9X_asp.net что async
и await
достаточно новы, и я не могу найти 9X_c# ничего окончательного.
TL; DR: может ли HttpContext.Current
потенциально 9X_asp.net-website null
после await
?
- @DarrelMiller Скорее наоборот. Я отделил бизнес-логику от реального веб-проекта. Используя внедрение зависимостей, я могу добавить библиотеку с поддержко ...
Ответ #1
Ответ на вопрос: Почему HttpContext.Current имеет значение null после ожидания?
Убедитесь, что вы пишете приложение ASP.NET 9X_c# 4.5 и ориентируетесь на 4.5. async
и await
имеют неопределенное 9X_async-await поведение в ASP.NET, если вы не работаете 9X_visual-c# в 4.5 и не используете новый «удобный для 9X_c#.net задач» контекст синхронизации.
В частности, это 9X_async-await означает, что вы должны:
- Установите для
httpRuntime.targetFramework
значение4.5
или - В
appSettings
установите дляaspnet:UseTaskFriendlySynchronizationContext
значениеtrue
.
Дополнительная информация 9X_asp-net available here.
- Я только что создал новый проект ASP.NET 4.5 WebAPI, скопировал / вставил ваш код и провел тест. У меня это сработало отлично (ни одно исключение не было выбран ...
Ответ #2
Ответ на вопрос: Почему HttpContext.Current имеет значение null после ожидания?
Как правильно указал @StephenCleary, вам 9X_aspdotnet нужно это в вашем web.config:
Когда я впервые 9X_aspx устранял эту неполадку, я выполнил поиск 9X_c-sharp вышеуказанного решения по всему решению, подтвердил, что 9X_csharp он присутствует во всех моих веб-проектах, и 9X_.net-async-await быстро отклонил его как виновника. В конце 9X_.net-async-await концов мне пришло в голову взглянуть на 9X_asp.net эти результаты поиска в полном контексте:
Дох.
Урок: если 9X_aspx вы обновляете веб-проект до версии 4.5, вам 9X_asp.net-website все равно нужно настроить этот параметр 9X_aspdotnet вручную.
- Еще одна проблема: это отличается от <compilat ...
Ответ #3
Ответ на вопрос: Почему HttpContext.Current имеет значение null после ожидания?
Недавно я столкнулся с этой проблемой. Как 9X_csharp отметил Стивен, отсутствие явной настройки 9X_asp.net-web-api целевой платформы может вызвать эту проблему.
В 9X_c-sharp моем случае наш веб-API был перенесен в 9X_csharp версию 4.6.2, но целевая среда выполнения 9X_async-ctp никогда не была указана в веб-конфигурации, поэтому 9X_await в основном это отсутствовало внутри тега 9X_asp-net :
Если у вас есть сомнения по поводу используемой 9X_c# версии фреймворка, это может помочь: Добавьте 9X_async-await следующую строку в любой из ваших методов 9X_async-await веб-API и установите точку останова, чтобы 9X_c# проверить, какой тип в настоящее время загружен 9X_aspx во время выполнения, и убедиться, что это 9X_c#.net не устаревшая реализация:
Вы должны увидеть 9X_await это (AspNetSynchronizationContext):
Вместо 9X_async-ctp LegazyAspNetSynchronizationContext (что 9X_c# я видел перед добавлением целевой платформы):
Если 9X_.net-async-await вы перейдете к исходному коду (https://referencesource.microsoft.com/#system.web/LegacyAspNetSynchronizationContext.cs), вы увидите, что 9X_visual-c# в устаревшей реализации этого интерфейса 9X_csharp отсутствует поддержка асинхронности.
Я потратил 9X_c#.net много времени, пытаясь найти источник проблемы, и 9X_aspx ответ Стивена мне очень помог. Надеюсь, этот 9X_.net-async-await ответ предоставит дополнительную информацию 9X_c#-language о проблеме.
Ответ #4
Ответ на вопрос: Почему HttpContext.Current имеет значение null после ожидания?
Есть ли у меня ошибки в тесте или мне не 9X_c#.net хватает какого-то элемента web.config? здесь, чтобы 9X_c#-language HttpContext.Current разрешился правильно 9X_asp.net после ждать?
Ваш тест не содержит ошибок, и 9X_aspdotnet HttpContext.Current не должен иметь значение 9X_asp.net-web-api null после ожидания, потому что в веб-API 9X_async-await ASP.NET, когда вы ожидаете, это гарантирует, что 9X_c#-language код, следующий за этим ожиданием, будет 9X_asp-net передан правильный HttpContext, который 9X_c#-language присутствовал до жду.
- HttpContext.Current имеет значение null после ожидания в моем коде, и я нацелен на .net 4. ...
Ответ #5
Ответ на вопрос: Почему HttpContext.Current имеет значение null после ожидания?
Я хотел прокомментировать и сказать, что 9X_c#.net предыдущие ответы попали в точку с точки зрения web.config, однако 9X_asp.net-website могут быть унаследованы настройки от IIS, которые 9X_asp.net-website могут переопределить эту функцию, если вы 9X_c-sharp просто используйте .
Что я имею в виду: Настоящее 9X_asp.net исправление здесь - это настройка:
Если 9X_c-sharp вы явно не включаете этот параметр, но полагаетесь 9X_await на для настройки этого параметра, он будет 9X_aspx отменен любыми параметрами в IIS.
Если вы 9X_c# отлаживаете или регистрируете тип SynchronizationContext 9X_await и обнаруживаете, что это тип Legacy, вы 9X_asp.net можете проверить настройку на уровне IIS 9X_asp.net или хостинг-сайта.
Будет выдан LegacyAspNetSynchronizationContext:
Web.config:
выдаст AspNetSynchronizationContext (это то, что вы хотите):
* Обратите 9X_async-ctp внимание, что здесь нет настройки переопределения 9X_aspx в IIS
-
8
-
4
-
3
-
1
-
3
-
1
-
3
-
1
-
1
-
2
-
2
-
1
-
2
-
2
-
5
-
7
-
3
-
3
-
11
-
2
-
2
-
2
-
6
-
1
-
5
-
2
-
1
-
4
-
2
-
2
-
6
-
5
-
15
-
7
-
3
-
7
-
6
-
8
-
3
-
4
-
2
-
3
-
9
-
6
-
4
-
3
-
21
-
5
-
1
-
4