C# Async Await异步总结

新公司项目里大量使用Async Await,所以最近几天看了一些讲解Async/Await的文章和教程,有些理解也有些疑惑,先记录下。

控制台示例:

 1         static void Main(string[] args)
 2         {
 3             Console.WriteLine("主线程:" + Thread.CurrentThread.ManagedThreadId);
 4             TestAsync();
 5             Console.WriteLine("GetInfoAsync后 调用线程:" + Thread.CurrentThread.ManagedThreadId);
 6             Thread.Sleep(5000);
 7             Console.ReadLine();
 8         }
 9         public async static Task TestAsync() {
10             Console.WriteLine("await1前 调用线程:" + Thread.CurrentThread.ManagedThreadId);
11             await Task.Run(()=> {
12                 Console.WriteLine("await1 调用线程:" + Thread.CurrentThread.ManagedThreadId);
13                 Thread.Sleep(5000);
14             }); 
15             Console.WriteLine("await1后 调用线程:" + Thread.CurrentThread.ManagedThreadId);
16             await Task.Run(() => {
17                 Console.WriteLine("await2 调用线程:" + Thread.CurrentThread.ManagedThreadId);
18                 Thread.Sleep(5000);
19             });
20             Console.WriteLine("await2后 调用线程:" + Thread.CurrentThread.ManagedThreadId);
21         }

运行结果:

通过运行结果可以看出代码的运行顺序。主线程会进入TestAsync方法,此时并没有异步。

1,当主线程1遇到第一个await时

2,一方面主线程1会暂停TestAsync方法并返回,继续执行Main方法中TestAsync()后边的代码,直到Main方法结束然后被释放;

3,另一方面新线程3被创建,并执行await后的参数和代码。线程1和线程3互不影响,并行运行。

4,线程3执行到第二个await时,线程3会暂停TestAsync方法并返回(应该没处返回了,Main已经运行结束了),执行结束后被释放

5,新线程4被创建,并执行await后的参数和代码。

 

不使用async await时,也运行下用以比较:

 1         static void Main(string[] args)
 2         {
 3             Console.WriteLine("主线程:" + Thread.CurrentThread.ManagedThreadId);
 4             Test();
 5             Console.WriteLine("GetInfoAsync后 调用线程:" + Thread.CurrentThread.ManagedThreadId);
 6             Thread.Sleep(5000);
 7             Console.ReadLine();
 8         }
 9 
10         public static void Test() {
11             Console.WriteLine("await1前 调用线程:" + Thread.CurrentThread.ManagedThreadId);
12             Task.Run(() => {
13                 Console.WriteLine("await1 调用线程:" + Thread.CurrentThread.ManagedThreadId);
14                 Thread.Sleep(5000);
15             });
16             Console.WriteLine("await1后 调用线程:" + Thread.CurrentThread.ManagedThreadId);
17              Task.Run(() => {
18                 Console.WriteLine("await2 调用线程:" + Thread.CurrentThread.ManagedThreadId);
19                 Thread.Sleep(5000);
20             });
21             Console.WriteLine("await2后 调用线程:" + Thread.CurrentThread.ManagedThreadId);
22         }

运行结果:

 

 

总结:

1,await关键字可以使后边代码异步,不阻塞主线程

2,用同步方式(看起来是同步,执行顺序一目了然)写异步代码。如果不使用await,想要实现相似的异步效果,要写很多嵌套。

3,频繁释放线程,增加程序吞吐性

4,asp.net程序、winform和WPF程序会有死锁问题

5,底层原理可反编译查看

6,C#5.0语法糖

 

疑惑:一个asnyc方法里写多个await有什么意义?

解惑:每个await都会释放当前线程并创建新线程。要不阻塞主线程,至少要使用一个await。

使用多个await,一方面增加程序吞吐性;另一方面,探索中。。

 

参考:C#异步编程async/await用法详解浅谈Await 

 

posted @ 2022-12-02 19:36  小小的阳光  阅读(1924)  评论(0)    收藏  举报