.NET为什么要使用异步(async)编程?
有几点坐下笔记
⭐⭐⭐⭐:
1. 同步方法
static void Main(string[] args) { Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ms")}:开始"); // 调用同步方法 SyncTestMethod(); Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ms")}:结束"); Console.ReadKey(); } /// <summary> /// 同步方法 /// </summary> static void SyncTestMethod() { for (int i = 0; i < 10; i++) { var str = $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ms")}:SyncTestMethod{i}"; Console.WriteLine(str); Thread.Sleep(10); } }
控制台打印:
2019-03-26 14:44:05 445:开始 2019-03-26 14:44:05 445:SyncTestMethod0 2019-03-26 14:44:05 445:SyncTestMethod1 2019-03-26 14:44:05 445:SyncTestMethod2 2019-03-26 14:44:05 445:SyncTestMethod3 2019-03-26 14:44:05 445:SyncTestMethod4 2019-03-26 14:44:05 445:SyncTestMethod5 2019-03-26 14:44:05 445:SyncTestMethod6 2019-03-26 14:44:05 445:SyncTestMethod7 2019-03-26 14:44:05 445:SyncTestMethod8 2019-03-26 14:44:05 445:SyncTestMethod9 2019-03-26 14:44:05 445:结束
主线程在调用同步方法时,会直接在主线程中执行同步方法,这个时候若SyncTestMethod方法后面还有其它方法,都需要等待SyncTestMethod执行完成。(就是要有个先来后到)
2. 异步方法
static void Main(string[] args) { Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ms")}:开始"); // 调用异步步方法 AsyncTestMethod(); Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ms")}:结束"); Console.ReadKey(); } /// <summary> /// 异步方法 /// </summary> /// <returns></returns> static async Task AsyncTestMethod() { await Task.Run(() => { for (int i = 0; i < 10; i++) { Console.WriteLine($"AsyncTestMethod"); Thread.Sleep(10); } }); }
控制台打印:
2019-03-26 14:52:37 5237:开始 2019-03-26 14:52:37 5237:结束 2019-03-26 14:52:37 5237:AsyncTestMethod 2019-03-26 14:52:37 5237:AsyncTestMethod 2019-03-26 14:52:37 5237:AsyncTestMethod 2019-03-26 14:52:37 5237:AsyncTestMethod 2019-03-26 14:52:37 5237:AsyncTestMethod 2019-03-26 14:52:37 5237:AsyncTestMethod 2019-03-26 14:52:37 5237:AsyncTestMethod 2019-03-26 14:52:37 5237:AsyncTestMethod 2019-03-26 14:52:37 5237:AsyncTestMethod 2019-03-26 14:52:37 5237:AsyncTestMethod
主线程在调用异步方法时,默认还是会在主线程中执行,但是如果异步方法中使用了
Task.Run(()=>{}) 这种方式执行异步任务,异步任务将会在一个独立的线程去执行异步方法,
Task.Run(()=>{}) 这种方式执行异步任务,异步任务将会在一个独立的线程去执行异步方法,
调用过AsyncTestMethod方法之后,不会阻塞主线程并直接执行AsyncTestMethod后面的主线程其它方法(就是把异步的程式给另外一个人做,个人干个人的,互相不干扰),
这个时候主线程也不会等待异步方法执行完成。
并且这个时候主线程无法知晓异步方法会在什么时候执行完成(两个人不知道谁先干完,谁啥时候干完),
所以此时也无法在主线程中直接获取异步方法的返回,
⭐⭐⭐⭐如果需要在异步方法执行完成之后再在主线程中执行其它方法,则需要使用Wait()来等待异步任务执行完成。⭐⭐⭐⭐
![](https://img2018.cnblogs.com/i-beta/1089332/201911/1089332-20191129123615851-1951906523.png)
3. 等待(awiat)异步方法
static void Main(string[] args) { Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ms")}:开始"); // 调用异步步方法 AsyncTestMethod(); // 等待异步方法执行完成 m1.Wait();/////////////////////////////////////这里出现awit这个关键字,就是主线程,等待异步线程完成 Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ms")}:结束"); Console.ReadKey(); } /// <summary> /// 异步方法 /// </summary> /// <returns></returns> static async Task AsyncTestMethod() { await Task.Run(() => { for (int i = 0; i < 10; i++) { Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ms")}:AsyncTestMethod"); Thread.Sleep(10); } }); }
控制台打印:
2019-03-26 14:55:51 5551:开始 2019-03-26 14:55:51 5551:AsyncTestMethod 2019-03-26 14:55:51 5551:AsyncTestMethod 2019-03-26 14:55:51 5551:AsyncTestMethod 2019-03-26 14:55:51 5551:AsyncTestMethod 2019-03-26 14:55:51 5551:AsyncTestMethod 2019-03-26 14:55:51 5551:AsyncTestMethod 2019-03-26 14:55:51 5551:AsyncTestMethod 2019-03-26 14:55:51 5551:AsyncTestMethod 2019-03-26 14:55:51 5551:AsyncTestMethod 2019-03-26 14:55:51 5551:AsyncTestMethod 2019-03-26 14:55:51 5551:结束
主线程在调用异步方法时,由于使用了Task.Run(()=>{}) 创建异步任务,所以异步任务会在一个独立的线程去执行,
然后在调用AsyncTestMethod方法之后执行了对AsyncTestMethod方法的等待Wait(),这个时候主线程会等待异步方法执行完成,不会执行后续的方法,
在AsyncTestMethod执行完成之后,等待结束,此时可以拿到异步方法AsyncTestMethod的返回值(就是加了awit的作用,让主线程等待异步线程)
然后再继续执行主线程中的后继方法。
![](https://common.cnblogs.com/images/loading.gif)
![](https://img2020.cnblogs.com/blog/1089332/202007/1089332-20200722093015774-1289653525.png)