2009-12-27 111 views
2

我試圖找出如何工作的。瞭解異步HttpWebRequest的

HttpWebRequest有一個方法BeginGetResponse它接受作爲參數ResponseCallback。首先,這個回調叫做立即(在一個新的線程中),或者一旦它從服務器收到迴應?或者是EndGetResponse等待迴應的工作?其次,一旦你有了迴應,你可以立即訪問響應流,但是這個流在下載完成之前並不包含整個頁面,因此BeginRead。但是,我似乎能夠通過像HttpWebResponse.ContentLength這樣的屬性立即訪問所有標題。這是否意味着EndGetResponse沒有完成,直到頭被完全下載,或者,當你調用ContentLength參數它掛了一會兒,直到收到難道是頭?

回答

5

的開始*和結束*模式始終是相同的:

  • 通行證在一個AsyncCallback開始
  • 等待回調的調用(即時)
  • 呼叫結束* 總是在回調中
  • 檢查回調/ IAsyncResult是否成功(是否 取消?任何異常/錯誤?)
  • 使用End *的結果..

您的情況的結果是一個WebResponse實例,它包含Headers。所以我認爲可以肯定的是,已經收到響應的那部分:WebResponse對象的屬性中沒有隱藏的異步魔術。如果訪問ContentLength,它只是一個常規屬性,對象不知道或不在乎是否使用阻塞或異步調用獲取它。

+0

所以你覺得ResponseCallback不叫,直到頭下載?很公平。你知道如何檢查它是否被取消,或者是檢查'EndGetResponse'拋出的異常的唯一方法嗎? – mpen

+0

除非您實現取消此操作的方式,否則我不知道如何停止此特定方法 - 它作爲ThreadPool上的一項操作運行,您和用戶現在都無法停止它。一般模式通過延長合同來允許更好的取消機制。例如WebClient就是這樣做的,並允許您訂閱獲取AsyncCompletedEventArgs實例的事件,該實例再次提供.Cancelled屬性。這是基於上面給出的模式的純粹便利的東西。 –

+0

它可以很容易地實際停止:'ThreadPool.RegisterWaitForSingleObject(asyncResult.AsyncWaitHandle,TimeoutCallback,康涅狄格州,TimeOutInterval,真);'我想,而我在這我可以添加自己的'Cancelled'財產。 'WebClient'並沒有完全達到我想要的效果,所以我將它重建得更加靈活一些,並支持多個併發下載。 – mpen