.Net WebRequest异步请求与WebClient异步请求

不少状况下通常会使用同步方式发出请求,直到响应后再作后续的逻辑处理等,但有时候后续的逻辑处理不依赖于请求的结果或者是能够挂起等到响应后再处理,又或者是为了解决UI“假死”的现象,这时能够使用异步请求服务器

使用WebRequest实例中的BeginGetResponse方法异步获取响应结果,其中参数callback是委托类型,state是自定义的对象,state用于保存一些信息,在callback对应的方法中可能须要用到这些信息。异步

下面用一个例子说明,假设须要请求url,该url对应是一张图片,异步获取后展现到PictureBox中(该例子基于winform的一个窗体中)url

winform中定义了存放数据的变量spa

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

在具体须要请求服务器的地方建立WebRequest实例,并调用BeginGetResponse方法code

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以下:orm

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。blog

 

若是是使用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); } }
相关文章
相关标签/搜索