У меня есть веб-приложение положение в большой степени на веб-сервисы. Все с сервисами сделано асинхронно и с AddOnPreRequestHandlerExecuteAsync. Во всяком случае большинство моих вызовов работает просто великолепно, но некоторые возвращаются из их асинхронных вызовов служб для нахождения пустого HttpContext. Текущий. Объект ответа/Запроса в endprerequest, который, конечно, ошибки момент я пытаюсь использовать также. Оба объекта (Ответ и Запрос являются доступным/не пустым указателем на beginprerequest сбоя вызовов и работы в endprerequest других вызовов).
Кто-либо сталкивается подобный, или имеет предположение относительно того, какова могла бы быть проблема?
Обновление: Кажется, нашел решение, если я создаю переменную для HttpApplication на Init (HttpModule, это все происходит в), к HttpContext можно получить доступ от той переменной.
Обновление: Передача или HttpApplication или HttpContext. Текущий на начальной функции имеет ту же проблему. При передаче как часть "состояния" асинхронного вызова они заканчивают пустой указатель в конечной функции, даже при том, что они допустимы в начальной функции.
Обновление: я добавил некоторый вход и нашел, что Асинхронный вызов, который я выполняю, возвращается правильно, результаты там, функция обратного вызова вызывается правильно.
Кажется, нашлось решение, если я создаю переменную для HttpApplication на Init(модуля HttpModule, в котором все это происходит), то из этой переменной можно получить доступ к HttpContext.
. Я подозреваю, что знаю, с какой проблемой вы столкнулись. Ответ, почти наверняка, состоит в том, чтобы заменить использование HttpWebRequest
на WebClient
, а также использовать методы *Async WebClient
.
Вот длинное объяснение: Существует две совершенно разные модели программирования Async: IAsyncResult Async Pattern и Event-based Asynchronous Pattern. Шаблон IAsyncResult использует методы BeginXXX
и EndXXX
, использует экземпляры IAsyncResult, использует делегатов для обратных вызовов и поддерживает ожидание завершения. Шаблон, основанный на событиях, использует методы XXXAsync для инициирования асинхронных действий, использует XXXCompleted
события вместо обратных вызовов для обработки завершения, и (это важно в вашем случае) передает потокоспецифический контекст в каждый обработчик события обратного вызова. Другими словами, если вы поместите код обратного вызова в XXXCompleted обработчик события (например, WebClient.DownloadStringCompleted
), то HttpContext.current будет заполнен корректно. Однако, если вы используете метод BeginXXX (например, HttpWebRequest.BeginGetResponse
) и обратный вызов делегата, то ваш вызов будет выполнен в контексте потока, который не гарантирует наличие правильного ASP.NET-контекста.
Обычно, .NET-библиотека классов либо использует один шаблон асинхронизации, либо другой. Обычно классы нижнего уровня (например, HttpWebRequest
) используют шаблон IAsyncResult, в то время как классы верхнего уровня (например, WebClient
) используют шаблон, основанный на событиях. Некоторые нечетные классы (например, автоматически генерируемые .NET Remoting proxies) будут поддерживать оба шаблона, но это редкость.
Поэтому, если это легко сделать, я бы предложил перейти к WebClient и обработчикам событий вместо HttpWebRequest и делегатов обратного вызова. Это должно решить вашу проблему. Если переход на WebClient слишком сложен, прокомментируйте, и я, вероятно, смогу предложить несколько более непонятных альтернатив.