封装C#发送http请求成功后的callback
来源:互联网 发布:做浮雕的软件 编辑:程序博客网 时间:2024/05/22 01:41
目的其实很简单,是想要封装一个发送http的post请求的函数。
函数参数填url地址、请求参数、以及得到后台相应的回调函数、访问超时时间
形如:
public void HttpPost(string url, Dictionary<string, string> dic , Action<IAsyncResult> callback,int timeout)
网上找了之后发现HttpWebRequest 这个类可以实现这个功能
于是网上查到可以这么写
/// <summary> /// 异步post /// </summary> public void HttpPost(string url, Dictionary<string, string> dic , Action<string> callback) { Uri uri = new Uri(url); HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri); request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; HttpReqPack pack = new HttpReqPack(request, dic, callback); request.BeginGetRequestStream(new AsyncCallback(RequestProceed), pack); }这里的pack是自己封装的,目的是为了在BeginGetRequestStream这个函数第二个参数传入一些请求相关信息的数据,因为这个函数的第一个参数是一个委托,第二个参数是带入这个委托的参数其实主要的工作是在RequestProceed这个函数里完成的。以下是HttpReqPack类以及RequestProceed函数的定义。
HttpReqPack类:
class HttpReqPack { public HttpWebRequest request; public Dictionary<string, string> dic; public Action<string> responesProceed; public HttpReqPack(HttpWebRequest request, Dictionary<string, string> dic, Action<string> responseProceed) { this.request = request; this.dic = dic; this.responesProceed = responseProceed; } }
private void RequestProceed(IAsyncResult asyncResult) { HttpReqPack pack = (HttpReqPack)asyncResult.AsyncState; Dictionary<string, string> dic = pack.dic; HttpWebRequest request = pack.request;//(HttpWebRequest)asyncResult.AsyncState; StreamWriter postDataWriter = new StreamWriter(request.EndGetRequestStream(asyncResult)); int i = 0; foreach (var item in dic) { if(i==0) postDataWriter.Write(item.Key+"="+item.Value); else postDataWriter.Write("&"+item.Key + "=" + item.Value); i++; } postDataWriter.Close(); request.BeginGetResponse(t=> { String responseString; try { HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(t); StreamReader responseReader = new StreamReader(response.GetResponseStream()); responseString = responseReader.ReadToEnd(); } catch(Exception e) { responseString = JsonConvert.SerializeObject(new ReturnMsg(PublicVar.SVR_UNKNOW_ERROR, e.Message)); } //调用一下委托 pack.responesProceed.Invoke(responseString); }, request); }在这函数中,就用到了刚才封装的那个HttpReqPack类,把发送参数、url地址还有最重要的是刚才构造的HttpWebRequest对象取出来使用。这个HttpWebRequest对象把他保存在一个名为request的对象,他有个BeginGetResponse方法,这个方法才是发起网络请求的核心方法(经过后期打印日志发现,最耗时的方法也是这个),第一个参数仍然是一个带一个参数无返回值的委托,为了简洁代码,我使用了一个lambda表达式来写,BeginGetResponse的第二个参数是request对象本身就不多说了。
这个委托带的一个参数是HttpWebRequest类型的request对象本身,委托的方法体内使用了另一个重要的方法EndGetResponse,这个方法作用是等待刚才发起的网络请求的结束,当然也可能抛异常,比如网络地址不存在等等,所以用了try..catch..去捕获。EndGetResponse函数的返回值是HttpWebResponse 类型的,把结果保存在response变量,就可以得到最终的后台返回的数据。
最后,调用事先保存在pack中的responesProceed方法,去回调到外层最初调用HttpPost函数的地方。
调用地方的代码可以这样:
new HttpClient().HttpPost(url, dic, t=> { String responseString = t; MessageBox.Show(responseString); });
到目前为止,差不多已经完成了,可是还差一个超时时间设置,我希望自己设置http请求的超时时间,这个如何解决?
尝试了设置request的
request.Timeout = timeout;
request.ReadWriteTimeout = 1;
这两个属性都不管用。
查看了msdn里HttpWebRequest.BeginGetResponse函数,参考里面的例子代码。完成了异步类型超时的设置方式,以下是完整的代码:
using Charge.Public;using Charge.Record;using Newtonsoft.Json;using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Net;using System.Net.Http;using System.Text;using System.Threading;namespace Charge{ class HttpSender { class HttpReqPack { public RequestState requestState; public Dictionary<string, string> dic; public Action<string> responesProceed; public int timeout; public HttpReqPack(RequestState requestState, Dictionary<string, string> dic, Action<string> responseProceed,int timeout) { this.requestState = requestState; this.dic = dic; this.responesProceed = responseProceed; this.timeout = timeout; } } /// <summary> /// 异步post /// </summary> public void HttpPost(string url, Dictionary<string, string> dic , int timeout, Action<string> callback) { Uri uri = new Uri(url); RequestState myRequestState = new RequestState(); HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri); myRequestState.request = request; request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; HttpReqPack pack = new HttpReqPack(myRequestState, dic, callback, timeout); request.BeginGetRequestStream(new AsyncCallback(RequestProceed), pack); } // Abort the request if the timer fires. private static void TimeoutCallback(object state, bool timedOut) { if (timedOut) { HttpWebRequest request = state as HttpWebRequest; if (request != null) { request.Abort(); } } } public static ManualResetEvent allDone = new ManualResetEvent(false); private void RequestProceed(IAsyncResult asyncResult) { HttpReqPack pack = (HttpReqPack)asyncResult.AsyncState; Dictionary<string, string> dic = pack.dic; HttpWebRequest request = pack.requestState.request; StreamWriter postDataWriter = new StreamWriter(request.EndGetRequestStream(asyncResult)); int i = 0; foreach (var item in dic) { if(i==0) postDataWriter.Write(item.Key+"="+item.Value); else postDataWriter.Write("&"+item.Key + "=" + item.Value); i++; } postDataWriter.Close(); LogHelper.WriteDebug("http计时程序", " request.BeginGetResponse"); try { IAsyncResult result = request.BeginGetResponse(t=> { String responseString; try { LogHelper.WriteDebug("http计时程序", " request.EndGetResponse"); HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(t); LogHelper.WriteDebug("http计时程序", " response.GetResponseStream()"); StreamReader responseReader = new StreamReader(response.GetResponseStream()); LogHelper.WriteDebug("http计时程序", "responseReader.ReadToEnd()"); responseString = responseReader.ReadToEnd(); LogHelper.WriteDebug("http计时程序", " 完成"); } catch(Exception e) { responseString = JsonConvert.SerializeObject(new ReturnMsg(PublicVar.SVR_UNKNOW_ERROR, e.Message)); } //调用一下委托 pack.responesProceed.Invoke(responseString); }, request); // this line implements the timeout, if there is a timeout, the callback fires and the request becomes aborted ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), request, pack.timeout, true); // The response came in the allowed time. The work processing will happen in the // callback function. allDone.WaitOne(); // Release the HttpWebResponse resource. pack.requestState.response.Close(); } catch (Exception e) { LogHelper.WriteDebug("报错", e.Message); } } }}
0 0
- 封装C#发送http请求成功后的callback
- //封装发送http请求的工具包
- C#发送HTTP请求
- C#发送 http请求
- C#发送http请求
- 封装js发送http请求
- C#发送Post方式的Http请求
- HttpClient 发送 HTTP、HTTPS 请求的简单封装
- HttpClient 发送 HTTP、HTTPS 请求的简单封装
- HttpClient 发送 HTTP、HTTPS 请求的简单封装
- C#后台发送Http请求
- C#后台发送HTTP请求
- C#模拟发送http get、post请求的方式
- 封装ng2的Http请求
- C#通过Http发送Soap请求
- C# 发送Http请求 - WebClient类
- c#发送http请求get post
- C# Http 发送Post请求实例
- Openjudge 1.7 35:字符串的展开
- 阿里应用运维体系的变迁
- Socket编程封装的类
- [详解机器学习]机器学习之认知篇
- Observable
- 封装C#发送http请求成功后的callback
- mongodb 3.4 配置sharding分片
- 开篇摘要总结
- VM中解决Ubuntu不能全屏的问题
- STM32 延时函数解析
- redirect 和 forward详解
- 计数排序
- mysql 组合索引的顺序问题
- ZYNQ-702裸机之MIO使用