微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

异步方法,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 != )
        {
            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;
    }
}
View Code

HttpUtil.HttpGetAsync方法

 HttpGetAsync
async Task<string> HttpGetAsync(发送请求并获取相应回应数据
        HttpWebResponse response = await request.GetResponseAsync() .Empty;
    }
}
View Code

测试代码

 测试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();
}
View Code

测试截图:

我想知道 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;
}
View Code

 

 

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐