static async Task Main(string[] args)
{
using (HttpClient httpClient = new HttpClient())
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
var html = await httpClient.GetStringAsync("https://www.jd.com/");
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
}
}
通过Console.WriteLine(Thread.CurrentThread.ManagedThreadId); 可以在控制台输出线程Id。运行结果如下:
结论:线程Id发生了改变,也就是说两次完成两次输出时占用的不是同一个线程。
原因:await调用的等待期间,.Net会把当前的线程返还给线程池,当异步方法执行完毕后,框架会从线程池再取出来一个线程执行后续的代码。类似于去餐厅吃饭,进餐厅时为我们点菜的是服务员A,点完菜时,服务员A去服务其他客人了。到菜做好了,传菜的是服务员B了。
当然如果你点的是米饭,可能递给你得依旧是服务员A。异步方法如果不是特别耗时的操作,那么使用的还是同一个线程,例子如下:
using (HttpClient httpClient = new HttpClient())
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
//var html = await httpClient.GetStringAsync("https://www.jd.com/");
string content = await File.ReadAllTextAsync("../Resource/1.txt");
Console.WriteLine("文件内容" + content);
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
}
执行的结果如下:
原理:此处为CLR的优化,当要等待的时候发现已经执行结束,那么就没有必要切换线程了,剩下的代码继续在当前线程上执行。
版权声明:本文为weixin_42765260原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。