HttpWebRequest 的一个 异步封装
来源:互联网 发布:linux 创建多级目录 编辑:程序博客网 时间:2024/05/18 17:45
相信大家对HttpWebRequest这个类应该非常熟悉了吧。主要用它来模拟http请求,在有些时候我们需要用到它的异步处理,每次用的时候都要写很多代码,于是今天把它简单的封装了一下。虽然在C#4和C#5中它提供了很新方法是的异步更加简单,但是在一些老项目(还在用vs2005)上我们只能用C#2.0的语法来实现它的异步功能。
如图1,这里的RequestInfo类是请求信息的一个封装,ResponseInfo类是返回对象的一个封装,StateObject是一个内部状态保存对象类(我们不需要关心),RequestHttpWebRequest是HttpWebRequest的一个封装类,只有一个公共方法:
public void GetResponseAsync(RequestInfo info, Action<ResponseInfo> act)
using System;using System.Collections.Generic;using System.Text;using System.IO;using System.Data;using System.Data.OleDb;using System.Net;using System.Xml;using System.Net.Security;using System.Security.Cryptography.X509Certificates;[Serializable]public class RequestInfo{ public RequestInfo(string url) { Url = url; AllowAutoRedirect = true; } public string Url { set; get; } public byte[] PostData { set; get; } public WebHeaderCollection Headers { set; get; } public bool AllowAutoRedirect { set; get; } public Dictionary<string, string> ExternalData { set; get; }}[Serializable]public class ResponseInfo{ public RequestInfo RequestInfo { set; get; } public Stream ResponseContent { set; get; } public HttpStatusCode StatusCode { set; get; } public WebHeaderCollection Headers { set; get; } public string GetString(Encoding coding) { StringBuilder str = new StringBuilder(); Stream sr = ResponseContent; sr.Seek(0, SeekOrigin.Begin); byte[] data = new byte[1024 * 1024]; int readcount = sr.Read(data, 0, data.Length); while (readcount > 0) { str.Append(coding.GetString(data, 0, readcount)); readcount = sr.Read(data, 0, data.Length); } return str.ToString(); }}internal class StateObject{ public byte[] Buffer { set; get; } public ResponseInfo ResponseInfo { set; get; } public Stream ReadStream { set; get; } public HttpWebRequest HttpWebRequest { set; get; } public Action<ResponseInfo> Action { set; get; }}public class RequestHttpWebRequest{ static RequestHttpWebRequest() { ServicePointManager.DefaultConnectionLimit = 100; } public RequestHttpWebRequest() { ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); } private bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) { //直接确认,否则打不开 return true; } public void GetResponseAsync(RequestInfo info, Action<ResponseInfo> act) { HttpWebRequest webRequest; StateObject state; InitWebRequest(info, act, out webRequest, out state); try { if (info.PostData != null && info.PostData.Length > 0) { webRequest.Method = "POST"; webRequest.ContentType = "application/x-www-form-urlencoded"; webRequest.BeginGetRequestStream(EndRequest, state); } else { webRequest.BeginGetResponse(EndResponse, state); } } catch (Exception ex) { HandException(ex, state); } } void EndRequest(IAsyncResult ar) { StateObject state = ar.AsyncState as StateObject; try { HttpWebRequest webRequest = state.HttpWebRequest as HttpWebRequest; using (Stream stream = webRequest.EndGetRequestStream(ar)) { byte[] data = state.ResponseInfo.RequestInfo.PostData; stream.Write(data, 0, data.Length); } webRequest.BeginGetResponse(EndResponse, state); } catch (Exception ex) { HandException(ex, state); } } void EndResponse(IAsyncResult ar) { StateObject state = ar.AsyncState as StateObject; try { HttpWebResponse webResponse = state.HttpWebRequest.EndGetResponse(ar) as HttpWebResponse; state.ResponseInfo.StatusCode = webResponse.StatusCode; state.ResponseInfo.Headers = new WebHeaderCollection(); foreach (string key in webResponse.Headers.AllKeys) { state.ResponseInfo.Headers.Add(key, webResponse.Headers[key]); } state.ReadStream = webResponse.GetResponseStream(); state.ReadStream.BeginRead(state.Buffer, 0, state.Buffer.Length, ReadCallBack, state); } catch (Exception ex) { HandException(ex, state); } } void ReadCallBack(IAsyncResult ar) { StateObject state = ar.AsyncState as StateObject; try { int read = state.ReadStream.EndRead(ar); if (read > 0) { state.ResponseInfo.ResponseContent.Write(state.Buffer, 0, read); state.ReadStream.BeginRead(state.Buffer, 0, state.Buffer.Length, ReadCallBack, state); } else { state.ReadStream.Close(); state.HttpWebRequest.Abort(); if (state.Action != null) { state.Action(state.ResponseInfo); } } } catch (Exception ex) { HandException(ex, state); } } private void InitWebRequest(RequestInfo info, Action<ResponseInfo> act, out HttpWebRequest webRequest, out StateObject state) { webRequest = HttpWebRequest.CreateDefault(new Uri(info.Url)) as HttpWebRequest; webRequest.KeepAlive = true; webRequest.AllowAutoRedirect = info.AllowAutoRedirect; if (info.Headers != null && info.Headers.Count > 0) { foreach (string key in info.Headers.Keys) { webRequest.Headers.Add(key, info.Headers[key]); } } //webRequest.Proxy = WebProxy.GetDefaultProxy(); //webRequest.Proxy.Credentials = CredentialCache.DefaultCredentials; // webResponse.Headers.Get("Set-Cookie"); state = new StateObject { Buffer = new byte[1024 * 1024], HttpWebRequest = webRequest, Action = act, ResponseInfo = new ResponseInfo { RequestInfo = info, ResponseContent = new MemoryStream() } }; } private void HandException(Exception ex, StateObject state) { string message = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " : " + state.ResponseInfo.RequestInfo.Url + " : " + ex.Message; Console.WriteLine(message); }}
这里的几个类及其属性都很好明白,我就不说了。只是大家要注意一点的是ResponseInfo中ResponseContent属性是服务器返回的数据流,这里它是一个MemoryStream对象。
说说简单的调用吧
整个调用是不是很简单啊!有不对的地方欢迎大家拍砖!
- HttpWebRequest 的一个 异步封装
- HttpWebRequest 的异步封装
- 一个可同步调用异步执行的HttpWebRequest类
- HttpWebRequest类的简单封装
- 一个关于异步下载的封装
- 封装一个异步下载的工具包
- IHttpHandler、WebClient、HttpWebRequest的异步模式
- ios的一个架构小例子---异步请求的封装
- objective-c一个简单的异步下载的封装
- WP7 异步操作 HttpWebRequest
- C# HttpWebRequest 异步请求
- HttpWebRequest post请求的一个例子
- 使用HttpWebRequest的POST取得网页内容(异步操作)
- 封装一个 图片异步下载类
- C# HttpWebRequest人异步访问
- 自己封装的一个支持回调和独立线程的异步发送邮件的类
- Handler实现对一个网页的异步加载,并将过程封装
- 自己用HttpWebRequest写的一个天气预报小偷
- Android4.0使用socket编程时要注意的问题
- 提供免费vpn
- PHP源码分析之启动过程
- Easy-ui属性汇总
- jQuery笔记
- HttpWebRequest 的一个 异步封装
- java优化小结
- 用dojo实现页面控件阻塞的几种方法
- 这才叫专业精神 - jQuery库源代码的完整注释
- java多线程面试题
- daemon
- 退耦电容的布局
- Cscope的使用(领略Vim + Cscope的强大魅力)
- opencv将图片分成多个256*256像素的小图片