写了那么多async和await都是在winform中,因为winform可以很明显的看出异步的优势(不阻塞主线程,也就是不卡死窗体),一直不知道async和await真正的作用,最近写webapi的时候也发现了这个问题,因为webapi没有窗体谈不上阻塞不阻塞,然后就想知道async和await在webapi中的作用,本来我是这么想的,不加async和await,也就是同步方法,全部用同步方法,用户调用接口的时候也可以自己写成异步方式调用,所以我当时觉得webapi中是没有必要用的,直到我看到了这么一篇帖子:
https://www.cnblogs.com/xishuai/p/asp-net-async-await-and-exception-handling.html
这个博主用代码测试了async和await对于线程来说的作用,例如:在一段异步代码中
private async void button10_Click(object sender, EventArgs e)
{
//
Debug.WriteLine("主线程的线程ID:" + Thread.CurrentThread.ManagedThreadId.ToString("00"));
//string str = await Test_Async1();//
List<Task<string>> task_list = new List<Task<string>>();
task_list.Add(Test_Async1());
task_list.Add(Test_Async2());
task_list.Add(Test_Async3());
string[] strs = await Task.WhenAll(task_list.ToArray());
foreach(string s in strs)
{
Debug.WriteLine(s);
}
//Debug.WriteLine("str:" + str);
}
private async Task<string> Test_Async1()
{
Debug.WriteLine("线程01:await之前的线程ID:" + Thread.CurrentThread.ManagedThreadId.ToString("00"));
string str = await Task<string>.Run(() =>
{
Debug.WriteLine("线程01:中的线程ID:" + Thread.CurrentThread.ManagedThreadId.ToString("00"));
Thread.Sleep(3000);
return "11111";
});
Debug.WriteLine("线程01:await之后的线程ID:" + Thread.CurrentThread.ManagedThreadId.ToString("00"));
return str;
}
private async Task<string> Test_Async2()
{
Debug.WriteLine("线程02:await之前的线程ID:" + Thread.CurrentThread.ManagedThreadId.ToString("00"));
string str = await Task<string>.Run(() =>
{
Debug.WriteLine("线程02:中的线程ID:" + Thread.CurrentThread.ManagedThreadId.ToString("00"));
Thread.Sleep(3000);
return "22222";
});
Debug.WriteLine("线程02:await之后的线程ID:" + Thread.CurrentThread.ManagedThreadId.ToString("00"));
return str;
}
private async Task<string> Test_Async3()
{
Debug.WriteLine("线程03:await之前的线程ID:" + Thread.CurrentThread.ManagedThreadId.ToString("00"));
string str = await Task<string>.Run(() =>
{
Debug.WriteLine("线程03:中的线程ID:" + Thread.CurrentThread.ManagedThreadId.ToString("00"));
Thread.Sleep(3000);
return "33333";
});
Debug.WriteLine("线程03:await之后的线程ID:" + Thread.CurrentThread.ManagedThreadId.ToString("00"));
return str;
}
代码可以很清晰的看出,线程01执行时如果遇到了await,就会将线程01回线程池,此时线程01可以被其他代码拿出去使用,可以看到执行线程02和线程03时用的线程就是线程01,三个线程执行完会随机从线程池再抓一个出来执行之后的代码,就像这个博主说的:有点类似于地主不能容忍奴隶闲着做无意义的事,而是希望他们 24 小时不停工作一样。
结论: