.Net WebRequest異步請求與WebClient異步請求


很多情況下一般會使用同步方式發出請求,直到響應后再做后續的邏輯處理等,但有時候后續的邏輯處理不依賴於請求的結果或者是可以掛起等到響應后再處理,又或者是為了解決UI“假死”的現象,這時可以使用異步請求

使用WebRequest實例中的BeginGetResponse方法異步獲取響應結果,其中參數callback是委托類型,state是自定義的對象,state用於保存一些信息,在callback對應的方法中可能需要用到這些信息。

下面用一個例子說明,假設需要請求url,該url對應是一張圖片,異步獲取后展示到PictureBox中(該例子基於winform的一個窗體中)

winform中定義了存放數據的變量

List<byte> lstBuffer = new List<byte>(); byte[] buffers = new byte[8];

在具體需要請求服務器的地方創建WebRequest實例,並調用BeginGetResponse方法

string url = "http://localhost/1.jpg"; var request = WebRequest.Create(url); request.BeginGetResponse(RespCallBack, request);
RespCallBack方法如下,此處ar.AsyncState也就是上面調用BeginGetResponse方法中參數state對應的信息,也就是request
private void RespCallBack(IAsyncResult ar) { var request = ar.AsyncState as WebRequest; var response = request?.EndGetResponse(ar); Stream responseStream = response?.GetResponseStream(); responseStream?.BeginRead(buffers, 0, 8, ReadCallBack, responseStream); }

由於是異步,此處讀數據也是異步讀取,ReadCallBack如下:

private void ReadCallBack(IAsyncResult ar) { using (var responseStream = ar.AsyncState as Stream) { if (responseStream == null) return; var read = responseStream.EndRead(ar); if (read > 0) { lstBuffer.AddRange(buffers); responseStream.BeginRead(buffers, 0, 8, ReadCallBack, responseStream); } else { lstBuffer.AddRange(buffers); Stream s = new MemoryStream(lstBuffer.ToArray()); pictureBox1.Image = Image.FromStream(s); pictureBox1.SizeMode = PictureBoxSizeMode.Zoom; responseStream.Dispose(); } } }

每次讀一定的字節,填充到指定的容器中(lstBuffer),當數據還沒有讀取完畢就一直調用responseStream.BeginRead(buffers, 0, 8, ReadCallBack, responseStream);

當讀取完畢后,將讀取的數據(lstBuffer)轉換成圖片,賦值給pictureBox。

 

如果是使用WebClient的方式代碼量就少很多,調用DownloadDataAsync方法發起異步請求,注冊事件DownloadDataCompleted,當異步請求完成的時候會觸發 Wc_DownloadDataCompleted事件,Wc_DownloadDataCompleted事件中DownloadDataCompletedEventArgs類型的參數e包含一些信息,其中e.Result就是請求響應的結果(byte[]類型)

 

var wc = new WebClient(); wc.DownloadDataAsync(new Uri("http://localhost/1.jpg")); wc.DownloadDataCompleted += Wc_DownloadDataCompleted;

 

private void Wc_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e) { using (MemoryStream ms = new MemoryStream(e.Result)) { if (pictureBox1 != null) pictureBox1.Image = Image.FromStream(ms); } }

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com