2009-12-27 3 views
2

Я пытаюсь понять, как это работает.Понимание асинхронного HttpWebRequest

HttpWebRequest имеет способ BeginGetResponse, который принимает в качестве параметра a ResponseCallback. Во-первых, этот обратный вызов вызвал сразу (в новом потоке) или после получения ответа с сервера? Или это задача EndGetResponse ждать ответа?

Во-вторых, как только вы получите ответ, вы можете получить доступ к потоку ответов немедленно, но поток не содержит полную страницу, пока не завершит загрузку, следовательно BeginRead. Тем не менее, я, похоже, могу сразу получить доступ ко всем заголовкам через такие свойства, как HttpWebResponse.ContentLength. Означает ли это, что EndGetResponse не заполняется до тех пор, пока заголовки не будут полностью загружены, или это когда вы вызываете параметр ContentLength, он зависает бит до тех пор, пока этот заголовок не будет принят?

ответ

5

блока Begin * и End * шаблон всегда одинаков:

  • Pass в AsyncCallback, чтобы начать
  • Дождитесь вызова этой функции обратного вызова (не немедленного)
  • вызова End * всегда в обратный вызов
  • Проверьте успех обратного вызова/IAsyncResult (это было отмененные? Любые исключения/ошибки?)
  • Используйте результат от End * здесь ..

В результате в вашем случае является экземпляром WebResponse, который содержит заголовки. Поэтому я думаю, что можно с уверенностью предположить, что эта часть ответа уже получена: объект WebResponse не имеет асинхронной магии, скрытой в своих свойствах. Если вы получаете доступ к ContentLength, это просто регулярное свойство, и объект не знает и не заботится, если вы получили его с помощью блокировки или асинхронного вызова.

+0

Итак, вы думаете, что ResponseCallback не вызывается до загрузки заголовков? Справедливо. Вы знаете, как проверить, был ли он отменен, или это единственный способ проверить исключение, вызванное «EndGetResponse»? – mpen

+0

Если вы не реализуете способ отмены этой операции, я бы не знал, как этот конкретный метод можно остановить - он работает как операция на ThreadPool, и вы ни пользователь, ни пользователь не можете остановить его сейчас. Общая схема позволяет лучше отменить механизм, хотя, расширив контракт. Например, WebClient делает это и позволяет вам подписаться на события, которые получают экземпляр AsyncCompletedEventArgs, которые снова предоставляют свойство .Cancelled. Это чистый материал, основанный на приведенном выше шаблоне. –

+0

На самом деле это можно легко остановить: 'ThreadPool.RegisterWaitForSingleObject (asyncResult.AsyncWaitHandle, TimeoutCallback, conn, TimeOutInterval, true);' Я полагаю, что я мог бы добавить свое собственное свойство «Отказано», пока я нахожусь в нем. 'WebClient' не совсем делает то, что я хочу, поэтому я перестраиваю его, чтобы быть немного более гибким и поддерживать несколько одновременных загрузок. – mpen

Смежные вопросы