Как я могу ссылаться на HttpContext из асинхронных методов в ASP.NET Web API? - PullRequest
0 голосов
/ 10 октября 2019

Я работаю над веб-API, на котором работает только синхронный код. Я хотел включить определенные методы асинхронно и запустить несколько параллельных задач. Проблема заключается в том, что после включения асинхронных методов HttpContext.Current становится нулевым, когда он впоследствии упоминается в асинхронных методах.

В веб-API есть фильтр, помещенный в определенные методы контроллера, который выглядит примерно так:

public class AuthenticationTokenFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var email = // Get some stuff from the request and do some things with it.
        var id = // Get some stuff from the request and do some things with it.

        System.Web.HttpContext.Current.Items.Add("Property1", email);
        System.Web.HttpContext.Current.Items.Add("Property2", id);
    }

Впоследствии внедренный класс, называемый чем-то вроде ContextProvider, будет напрямую обращаться к HttpContext для получения этих свойств. Однако при вызове провайдера из асинхронных методов контекст имеет значение null, и мы получаем нулевую ссылку - исключение.

Я прочитал несколько сообщений на эту тему, и решение для меня не очевидно. Я попытался установить следующее в файле конфигурации:

<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />

и убедился, что нацелена более высокая версия, чем .NET 4.5 (она использует 4.6.1).

Другие, кажется, предполагают, что вы можете вызывать асинхронные методы с HttpContext, но я не знаю, как это сделать, и предпочел бы не вызывать HttpContext в каждом отдельном методе, ожидаемом в этой цепочке.

1 Ответ

0 голосов
/ 10 октября 2019

Вы не показали свой код, где вы на самом деле используете асинхронные методы, но я предполагаю, что вы используете .ConfigureAwait(false). Некоторые люди разбрызгивают .ConfigureAwait(false) везде, но это не так просто.

Параметр ConfigureAwait равен:

continueOnCapturedContext Boolean

true для попытки маршалинга продолжения обратно в исходный захваченный контекст;в противном случае false.

HttpContext доступен только в том же контексте, в котором запущен запрос. Таким образом, необходимо вернуться в тот же контекст, если вы собираетесь использовать HttpContext после ожидания асинхронного метода.

Так что, если у вас есть .ConfigureAwait(false) в вашем коде, удалите его.

Более подробное объяснение в этом ответе .

.
...