Почему 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?

101
3

  • @DarrelMiller Скорее наоборот. Я отделил бизнес-логику от реального веб-проекта. Используя внедрение зависимостей, я могу добавить библиотеку с поддержко ...
5
Общее количество ответов: 5

Ответ #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.

165
7

  • Я только что создал новый проект 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 вручную.

33
1

  • Еще одна проблема: это отличается от <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_Почему HttpContext.Current имеет значение null после ожидания?_visual-c#

Вместо 9X_async-ctp LegazyAspNetSynchronizationContext (что 9X_c# я видел перед добавлением целевой платформы):

9X_Почему HttpContext.Current имеет значение null после ожидания?_.net-async-await

Если 9X_.net-async-await вы перейдете к исходному коду (https://referencesource.microsoft.com/#system.web/LegacyAspNetSynchronizationContext.cs), вы увидите, что 9X_visual-c# в устаревшей реализации этого интерфейса 9X_csharp отсутствует поддержка асинхронности.

9X_Почему HttpContext.Current имеет значение null после ожидания?_async-await

Я потратил 9X_c#.net много времени, пытаясь найти источник проблемы, и 9X_aspx ответ Стивена мне очень помог. Надеюсь, этот 9X_.net-async-await ответ предоставит дополнительную информацию 9X_c#-language о проблеме.

7
0

Ответ #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 присутствовал до жду.

3
4

  • 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:

 

9X_Почему HttpContext.Current имеет значение null после ожидания?_aspdotnet

выдаст AspNetSynchronizationContext (это то, что вы хотите):

 

* Обратите 9X_async-ctp внимание, что здесь нет настройки переопределения 9X_aspx в IIS

1
0