C#中HttpWebRequest、WebClient、HttpClient的使用详解
httpwebrequest:
命名空间: system.net,这是.net创建者最初开发用于使用http请求的标准类。使用httpwebrequest可以让开发者控制请求/响应流程的各个方面,如 timeouts, cookies, headers, protocols。另一个好处是httpwebrequest类不会阻塞ui线程。例如,当您从响应很慢的api服务器下载大文件时,您的应用程序的ui不会停止响应。httpwebrequest通常和webresponse一起使用,一个发送请求,一个获取数据。httpwebrquest更为底层一些,能够对整个访问过程有个直观的认识,但同时也更加复杂一些。
//post方法 public static string httppost(string url, string postdatastr) { httpwebrequest request = (httpwebrequest)webrequest.create(url); request.method = "post"; request.contenttype = "application/x-www-form-urlencoded"; encoding encoding = encoding.utf8; byte[] postdata = encoding.getbytes(postdatastr); request.contentlength = postdata.length; stream myrequeststream = request.getrequeststream(); myrequeststream.write(postdata, 0, postdata.length); myrequeststream.close(); httpwebresponse response = (httpwebresponse)request.getresponse(); stream myresponsestream = response.getresponsestream(); streamreader mystreamreader = new streamreader(myresponsestream, encoding); string retstring = mystreamreader.readtoend(); mystreamreader.close(); myresponsestream.close(); return retstring; } //get方法 public static string httpget(string url, string postdatastr) { httpwebrequest request = (httpwebrequest)webrequest.create(url + (postdatastr == "" ? "" : "?") + postdatastr); request.method = "get"; request.contenttype = "text/html;charset=utf-8"; httpwebresponse response = (httpwebresponse)request.getresponse(); stream myresponsestream = response.getresponsestream(); streamreader mystreamreader = new streamreader(myresponsestream, encoding.getencoding("utf-8")); string retstring = mystreamreader.readtoend(); mystreamreader.close(); myresponsestream.close(); return retstring; }
webclient:
命名空间system.net,webclient是一种更高级别的抽象,是httpwebrequest为了简化最常见任务而创建的,使用过程中你会发现他缺少基本的header,timeoust的设置,不过这些可以通过继承httpwebrequest来实现。相对来说,webclient比webrequest更加简单,它相当于封装了request和response方法,不过需要说明的是,webclient和webrequest继承的是不同类,两者在继承上没有任何关系。使用webclient可能比httpwebrequest直接使用更慢(大约几毫秒),但却更为简单,减少了很多细节,代码量也比较少。
public class webclienthelper { public static string downloadstring(string url) { webclient wc = new webclient(); //wc.baseaddress = url; //设置根目录 wc.encoding = encoding.utf8; //设置按照何种编码访问,如果不加此行,获取到的字符串中文将是乱码 string str = wc.downloadstring(url); return str; } public static string downloadstreamstring(string url) { webclient wc = new webclient(); wc.headers.add("user-agent", "mozilla/5.0 (windows nt 10.0; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/76.0.3809.132 safari/537.36"); stream objstream = wc.openread(url); streamreader _read = new streamreader(objstream, encoding.utf8); //新建一个读取流,用指定的编码读取,此处是utf-8 string str = _read.readtoend(); objstream.close(); _read.close(); return str; } public static void downloadfile(string url, string filename) { webclient wc = new webclient(); wc.downloadfile(url, filename); //下载文件 } public static void downloaddata(string url, string filename) { webclient wc = new webclient(); byte [] bytes = wc.downloaddata(url); //下载到字节数组 filestream fs = new filestream(filename, filemode.create); fs.write(bytes, 0, bytes.length); fs.flush(); fs.close(); } public static void downloadfileasync(string url, string filename) { webclient wc = new webclient(); wc.downloadfilecompleted += downcompletedeventhandler; wc.downloadfileasync(new uri(url), filename); console.writeline("下载中。。。"); } private static void downcompletedeventhandler(object sender, asynccompletedeventargs e) { console.writeline(sender.tostring()); //触发事件的对象 console.writeline(e.userstate); console.writeline(e.cancelled); console.writeline("异步下载完成!"); } public static void downloadfileasync2(string url, string filename) { webclient wc = new webclient(); wc.downloadfilecompleted += (sender, e) => { console.writeline("下载完成!"); console.writeline(sender.tostring()); console.writeline(e.userstate); console.writeline(e.cancelled); }; wc.downloadfileasync(new uri(url), filename); console.writeline("下载中。。。"); } }
httpclient:
httpclient是.net4.5引入的一个http客户端库,其命名空间为 system.net.http ,.net 4.5之前我们可能使用webclient和httpwebrequest来达到相同目的。httpclient利用了最新的面向任务模式,使得处理异步请求非常容易。它适合用于多次请求操作,一般设置好默认头部后,可以进行重复多次的请求,基本上用一个实例可以提交任何的http请求。httpclient有预热机制,第一次进行访问时比较慢,所以不应该用到httpclient就new一个出来,应该使用单例或其他方式获取httpclient的实例
单例模式:
单例模式(singleton pattern)这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
单例创建步骤:1、定义静态私有对象;2、定义私有构造函数;3、提供公共获取对象方法;
单例模式一般分为两种实现模式:懒汉模式、饿汉模式(以下为java代码实现)
懒汉模式: 默认不会实例化,什么时候用什么时候new
public class singleton { private static singleton instance = null; private singleton (){} public static singleton getinstance() { if (instance == null) { instance = new singleton(); } return instance; } }
这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized,所以严格意义上它并不算单例模式。
这种方式 lazy loading 很明显,不要求线程安全,在多线程不能正常工作。
饿汉模式: 类初始化时,会立即加载该对象,线程天生安全,调用效率高
public class singleton { private static singleton instance = new singleton(); private singleton (){} public static singleton getinstance() { return instance; } }
双检锁/双重校验锁(dcl,即 double-checked locking):这种方式采用双锁机制,安全且在多线程情况下能保持高性能
public class singleton { private volatile static singleton singleton; private singleton (){} public static singleton getsingleton() { if (singleton == null) { synchronized (singleton.class) { if (singleton == null) { singleton = new singleton(); } } } return singleton; } }
httpclient:
public class httpclienthelper { private static readonly object lockobj = new object(); private static httpclient client = null; public httpclienthelper() { getinstance(); } public static httpclient getinstance() { if (client == null) { lock (lockobj) { if (client == null) { client = new httpclient(); } } } return client; } public async task<string> postasync(string url, string strjson)//post异步请求方法 { try { httpcontent content = new stringcontent(strjson); content.headers.contenttype = new system.net.http.headers.mediatypeheadervalue("application/json"); //由httpclient发出异步post请求 httpresponsemessage res = await client.postasync(url, content); if (res.statuscode == system.net.httpstatuscode.ok) { string str = res.content.readasstringasync().result; return str; } else return null; } catch (exception ex) { return null; } } public string post(string url, string strjson)//post同步请求方法 { try { httpcontent content = new stringcontent(strjson); content.headers.contenttype = new system.net.http.headers.mediatypeheadervalue("application/json"); //client.defaultrequestheaders.connection.add("keep-alive"); //由httpclient发出post请求 task<httpresponsemessage> res = client.postasync(url, content); if (res.result.statuscode == system.net.httpstatuscode.ok) { string str = res.result.content.readasstringasync().result; return str; } else return null; } catch (exception ex) { return null; } } public string get(string url) { try { var responsestring = client.getstringasync(url); return responsestring.result; } catch (exception ex) { return null; } } }
httpclient有预热机制,第一次请求比较慢;可以通过初始化前发送一次head请求解决:
_httpclient = new httpclient() { baseaddress = new uri(base_address) }; //帮httpclient热身 _httpclient.sendasync(new httprequestmessage { method = new httpmethod("head"), requesturi = new uri(base_address + "/") }) .result.ensuresuccessstatuscode();
三者区别列表:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 男人四大终极哲学问题
下一篇: web新手——新闻列表这样写不容易出错