当前位置: 首页 > 图灵资讯 > 技术篇> .net 中的async,await理解

.net 中的async,await理解

来源:图灵教育
时间:2023-06-06 09:27:30

理解:

1、async修饰的方法可以理解为异步法(必须与await配合,否则与普通方法无异)2、当async方法执行遇到await时,立即将控制权转移到async方法的调用者3、调用者决定是否需要等待async方法执行,然后继续执行4、await将悬挂当前方法,即阻止当前方法继续执行,将控制权转移给调用者

注:如果调用async方,请注意: 如果不使用await关键字来标记起点,程序将忽略async关键字并以同步的方式执行。编译器会警告类似的问题。

例1:(控制台程序)

1         static void Main(string[] args) 2         { 3             MyMain();//由于main方法不能定义为async,顾此定义了Mymain方法来表示main方法。 4             Console.Read(); 5         } 6         static async void MyMain() 7         { 8             Console.WriteLine(开始实施main方法); 9             AsyncAction();10             Console.WriteLine(继续实施main方法);11             Console.WriteLine(main方法执行结束);12         }13 14         static async Task<string> AsyncAction()15         {16             Console.WriteLine(Asyncaction方法await之前);17             string result = await Task<string>.Run(() =>18             {19                 Thread.Sleep(1000);20                 Console.WriteLine(Asyncaction方法sleep一秒后);21                 return “Asyncaction返回值”;22             });23             Console.WriteLine(Asyncaction方法await后-{0}” result);24             return result;25         }

执行结果:

.net 中的async,await理解_main方法

从返回结果可以看出,这种异步方法Asyncaction执行遇到await,即程序执行到此行时立即挂起,将控制权交给Mymain方法,Mymain决定是否等待Asyncaction执行后再往下执行。Asyncaction方法中的awaition Task.Run(包括)代码将异步执行。

例子二:例子一:MyMain方法执行Asyncaction前加awaition

1         static void Main(string[] args) 2         { 3             MyMain();//由于main方法不能定义为async,顾此定义了Mymain方法来表示main方法。 4             Console.Read(); 5         } 6         static async void MyMain() 7         { 8             Console.WriteLine(开始实施main方法); 9             await AsyncAction();10             Console.WriteLine(继续实施main方法);11             Console.WriteLine(main方法执行结束);12         }13 14         static async Task<string> AsyncAction()15         {16             Console.WriteLine(Asyncaction方法await之前);17             string result = await Task<string>.Run(() =>18             {19                 Thread.Sleep(1000);20                 Console.WriteLine(Asyncaction方法sleep一秒后);21                 return “Asyncaction返回值”;22             });23             Console.WriteLine(Asyncaction方法await后-{0}” result);24             return result;25         }

执行结果:

.net 中的async,await理解_记录日志_02

由于Asyncaction方法在执行前增加了await,Mymain方法必须等到执行结束后才能继续执行。

使用场景及用法分析:

当某个操作执行时间较长或执行结果对整个程序执行影响不大时(一般来说,这个操作是一种独立的方法。)主线程的执行不依赖于此操作的执行结果。它在一些IO操作中很常见,如日志记录。触发日志动作记录时,应单独执行一个线程。此时,无论日志记录是否成功,都不应阻止主线程的执行。在上面的例子一中,AsyncAction方法中可以使用 Task.Run 作为记录日志的动作,当程序执行到 await Task.Run后,Asyncaction方法立即挂起,主线程Mymain继续执行。有人可能会在这里提问?为什么不直接在主线程MyMain中打开线程呢? Task.Run 记录日志?相反,在AsyncAction方法中定义处理日志是必要的。是的,如果这个时候只是为了记录日志,那就不用写一个方法了。但是,首先,这种单一功能的操作应该是独立写在一种方法中。其次是 Asyncaction方法 中的 await Task.Run 返回值可能还有其他操作。

以下例子:在记录日志之前,您需要获取一些登录用户的信息,并将用户信息保存在日志中。如果您将其写入主线程Mymain,则无法避免堵塞主线程(因为您需要等待获取用户信息)。当然,您也可以将这两种方法写在一种方法中,由Task调用。这里只是一个例子来解释Async和Await的使用场景。

1         static void Main(string[] args) 2         { 3             MyMain();//由于main方法不能定义为async,顾此定义了Mymain方法来表示main方法。 4             Console.Read(); 5         } 6         static async void MyMain() 7         { 8             Console.WriteLine(开始实施main方法); 9             WriteUserLog();10             Console.WriteLine(继续实施main方法);11             Console.WriteLine(main方法执行结束);12         }13 14         static async void WriteUserLog()15         {16             Console.WriteLine(“在获取用户信息之前”);17             string userInfo = await GetUserInfoAsync(); ///尽早使用await,为了尽快挂起这种方法(异步执行)18             Console.WriteLine(写入日志前”);19             WriteLog(userInfo);20         }21 22         static Task<string> GetUserInfoAsync()23         {24             return Task.Factory.StartNew(() => {25                 Thread.Sleep(1000);26                 Console.WriteLine(“完成用户信息获取”);27                 return "jxf";28             });29         }30 31         static void WriteLog(string userInfo)32         {33             Thread.Sleep(1000);34             Console.WriteLine(写入日志完成,用户信息:{0} userInfo);35         }

执行结果:

.net 中的async,await理解_主线程_03