不知道用什么词形容,就叫它假异步吧。
写异步方法,async 和 await 要一路写vb.net教程到底,否则就是假异步,并不能提高请求线程池的吞吐量。
真正的异步,我的理解是这样的:比如调用一个查询接口,在当前线程,把SQL扔给数据库,当前线程释放,去干别的事情,数据库c#教程查询完了,通知我,我再在另一个线程里(也可能是刚才释放的那个线程,也可能不是)拿查询结果,返回给客户端,数据库查询比较耗时,数据库查询的时候,对线程是0占用。
HttpUtil.HttpGet方法:
复制代码
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;
Stream instream = response.GetResponseStream();
StreamReader sr = new StreamReader(instream, Encoding.UTF8);
string content = sr.ReadToEnd();
instream.Close();
return content;
}
catch (Exception ex)
{
LogUtil.Error(ex);
return string.Empty;
}
}
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
-
29
-
30
-
31
-
32
-
33
-
34
-
35
-
36
-
37
-
38
-
39
HttpUtil.HttpGetAsync方法:
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;
Stream instream = response.GetResponseStream();
StreamReader sr = new StreamReader(instream, Encoding.UTF8);
string content = sr.ReadToEnd();
instream.Close();
return content;
}
catch (Exception ex)
{
LogUtil.Error(ex);
return string.Empty;
}
}
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
-
29
-
30
-
31
-
32
-
33
-
34
-
35
-
36
-
37
-
38
-
39
测试代码:
private async void button1_Click(object sender, EventArgs e)
{
_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();
}
private async void button2_Click(object sender, EventArgs e)
{
_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();
}
private async Task<string> GetDataAsync()
{
return await Task.Run<string>(() =>
{
return HttpUtil.HttpGet("http://localhost:8500/api/test/TestGet?val=1", null, null);
});
}
private async Task<string> GetDataAsync2()
{
return await HttpUtil.HttpGetAsync("http://localhost:8500/api/test/TestGet?val=1", null, null);
}
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
-
29
-
30
-
31
-
32
-
33
-
34
-
35
-
36
-
37
-
38
-
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
-
47
-
48
-
49
-
50
-
51
-
52
-
53
-
54
-
55
-
56
-
57
-
58
-
59
测试截图:
我想知道 WebRequest 类的 GetResponseAsync 方法是怎么实现的,反正使用.NET提供的类,我是无法实现这样的方法。
这篇随笔如果有错误,请指正,我只是抛砖引玉,提出疑问或者说假设。
async await 要一路写到底啊,重构压力真大。
如果在异步方法中调用同步方法,又不想占用CLR线程池的线程,可以把耗时操作放到自己写的独立线程池中,例如:
[HttpGet]
[Route("TestGet")]
[SwaggerResponse(HttpStatusCode.OK, "返回JSON", typeof(JsonListResult<TestGetResult>))]
public async Task<HttpResponseMessage> TestGetAsync(string val)
{
var task = TaskHelper.RequestTask.Run(() =>
{
List<TestGetResult> list = new List<TestGetResult>();
Thread.Sleep(5000);
for (int i = 1; i <= 10; i++)
{
TestGetResult item = new TestGetResult();
item.testValue1 = i.ToString();
item.testValue2 = i;
item.testValue3 = "这是传入参数:" + val;
list.Add(item);
}
var jsonResult = new JsonListResult<TestGetResult>(list, list.Count);
return ApiHelper.ToJson(jsonResult);
});
return await task;
}