不知道用什么词形容,就叫它假异步吧。
写异步方法,async 和 await 要一路写到底,否则就是假异步,并不能提高请求线程池的吞吐量。
HttpUtil.HttpGet方法:
/// <summary> /// HttpGet </summary> <param name="url">url路径名称</param> <param name="cookie">cookie</param> public static string HttpGet(string url,CookieContainer cookie = null,WebHeaderCollection headers = null) { try { // 设置参数 HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; request.CookieContainer = cookie; request.Method = "GET"; request.ContentType = text/plain;charset=utf-8; if (headers != ) { foreach (string key in headers.Keys) { request.Headers.Add(key,headers[key]); } } 发送请求并获取相应回应数据 HttpWebResponse response = request.GetResponse() HttpWebResponse; 直到request.GetResponse()程序才开始向目标网页发送Post请求 Stream instream = response.GetResponseStream(); StreamReader sr = new StreamReader(instream,Encoding.UTF8); 返回结果网页(html)代码 string content = sr.ReadToEnd(); instream.Close(); return content; } catch (Exception ex) { LogUtil.Error(ex); return string.Empty; } }
HttpUtil.HttpGetAsync方法:
HttpGetAsync async Task<string> HttpGetAsync(发送请求并获取相应回应数据 HttpWebResponse response = await request.GetResponseAsync() .Empty; } }
测试代码:
测试1 </summary> private async void button1_Click(object sender,EventArgs e) { task是自己写的独立线程池,为了防止测试过程对CLR线程池和异步线程池造成干扰 _task.Run(() => { Thread.Sleep(200); int workerThreads1,completionPortThreads1,workerThreads2,completionPortThreads2; ThreadPool.GetMaxThreads(out workerThreads1,out completionPortThreads1); ThreadPool.GetAvailableThreads(out workerThreads2,1)"> completionPortThreads2); Log(假异步 已使用辅助线程:" + (workerThreads1 - workerThreads2) + ,已使用异步线程:" + (completionPortThreads1 - completionPortThreads2)); }); string str = await GetDataAsync(); } 测试2 void button2_Click(真异步 已使用辅助线程: GetDataAsync2(); } 假异步 string> GetDataAsync() { await Task.Run<string>(() =>接口耗时大约1秒 return HttpUtil.HttpGet(http://localhost:8500/api/test/TestGet?val=1",1)">); }); } 真异步 <returns></returns> GetDataAsync2() { 接口耗时大约1秒 await HttpUtil.HttpGetAsync(); }
测试截图:
我想知道 WebRequest 类的 GetResponseAsync 方法是怎么实现的,反正使用.NET提供的类,我是无法实现这样的方法。
这篇随笔如果有错误,请指正,我只是抛砖引玉,提出疑问或者说假设。
async await 要一路写到底啊,重构压力真大。
如果在异步方法中调用同步方法,又不想占用CLR线程池的线程,可以把耗时操作放到自己写的独立线程池中,例如:
测试GET请求 <param name="val">测试参数[HttpGet] [Route(TestGet)] [SwaggerResponse(HttpStatusCode.OK,返回JSONtypeof(JsonListResult<TestGetResult>))] async Task<HttpResponseMessage> TestGetAsync( val) { var task = TaskHelper.RequestTask.Run(() => 使用自己写的独立线程池 { List<TestGetResult> list = new List<TestGetResult>(); Thread.Sleep(5000); 模拟耗时 for (int i = 1; i <= 10; i++) { TestGetResult item = TestGetResult(); item.testValue1 = i.ToString(); item.testValue2 = i; item.testValue3 = 这是传入参数:" + val; list.Add(item); } var jsonResult = new JsonListResult<TestGetResult>(list,list.Count); ApiHelper.ToJson(jsonResult); }); task; }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。