2020-08-01

你可能写了个假异步,并不能提高请求线程池的吞吐量

不知道用什么词形容,就叫它假异步吧。

写异步方法,async 和 await 要一路写到底,否则就是假异步,并不能提高请求线程池的吞吐量。

真正的异步,我的理解是这样的:比如调用一个查询接口,在当前线程,把SQL扔给数据库,当前线程释放,去干别的事情,数据库查询完了,通知我,我再在另一个线程里(也可能是刚才释放的那个线程,也可能不是)拿查询结果,返回给客户端,数据库查询比较耗时,数据库查询的时候,对线程是0占用。 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 != null)  {   foreach (string key in headers.Keys)   {    request.Headers.Add(key, headers[key]);   }  }  //发送请求并获取相应回应数据  HttpWebResponse response = request.GetResponse() as HttpWebResponse;  //直到request.GetResponse()程序才开始向目标网页发送Post请求  Stream instream = response.GetResponseStream();  StreamReader sr = new StreamReader(instream, Encoding.UTF8);  //返回结果网页(html)代码  string content = sr.ReadToEnd();  return content; } catch (Exception ex) {  LogUtil.Error(ex);  return string.Empty; }}
View Code

HttpUtil.HttpGetAsync方法:

/// <summary>/// HttpGetAsync/// </summary>/// <param name="url">url路径名称</param>/// <param name="cookie">cookie</param>public static async Task<string> HttpGetAsync(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 != null)  {   foreach (string key in headers.Keys)   {    request.Headers.Add(key, headers[key]);   }  }  //发送请求并获取相应回应数据  HttpWebResponse response = await request.GetResponseAsync() as HttpWebResponse;  //直到request.GetResponse()程序才开始向目标网页发送Post请求  Stream instream = response.GetResponseStream();  StreamReader sr = new StreamReader(instream, Encoding.UTF8);  //返回结果网页(html)代码  string content = sr.ReadToEnd();  return content; } catch (Exception ex) {  LogUtil.Error(ex);  return string.Empty; }}
View Code

测试代码:

/// <summary>/// 测试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, out completionPortThreads2);  Log("假异步 已使用辅助线程:" + (workerThreads1 - workerThreads2) + ", 已使用异步线程:" + (completionPortThreads1 - completionPortThreads2)); }); string str = await GetDataAsync();}/// <summary>/// 测试2 /// </summary>private async void button2_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, out completionPortThreads2);  Log("真异步 已使用辅助线程:" + (workerThreads1 - workerThreads2) + ", 已使用异步线程:" + (completionPortThreads1 - completionPortThreads2)); }); string str = await GetDataAsync2();}/// <summary>/// 假异步/// </summary>private async Task<string> GetDataAsync(){ return await Task.Run<string>(() => {  //接口耗时大约1秒  return HttpUtil.HttpGet("", null, null); });}/// <summary>/// 真异步/// </summary>/// <returns></returns>private async Task<string> GetDataAsync2(){ //接口耗时大约1秒 return await HttpUtil.HttpGetAsync("", null, null);}
View Code

测试截图:

我想知道 WebRequest 类的 GetResponseAsync 方法是怎么实现的,反正使用.NET提供的类,我是无法实现这样的方法。

这篇随笔如果有错误,请指正,我只是抛砖引玉,提出疑问或者说假设。

 

你可能写了个假异步,并不能提高请求线程池的吞吐量推荐课程玩转Facebook之亚马逊流量聚焦与爆款打造亚马逊全球开店从0到1新手入门实操课节约30%以上成本:亚马逊FBA成本控制4要素!美国家居平台wayfair如何通过Facebook搜索精准找到客户?2017深圳清明想带孩子去放风筝?2017五一去哪里旅游好?2017年深圳哪里有年宵灯会?

No comments:

Post a Comment