C# 异步方法的执行流程
异步方法一般执行流程:
await 之前的代码同步运行在调用异步方法的线程里
当运行到await所在行后,调用线程在这里会立即返回,await等待的异步任务会被调度程序重新排队到线程池申请可用的工作线程异步执行
当await异步等待的任务完成后,await之后的代码重新排队从线程池中申请可用工作线程继续执行
示例:
1 static void Main(string[] args) 2 { 3 Console.WriteLine($"Main Begin ,CurrentThreadId:{Thread.CurrentThread.ManagedThreadId},是否线程池线程:{Thread.CurrentThread.IsThreadPoolThread}\r\n"); 4 5 Task<string> task1=TaskMethod0101("task1", 3); 6 //string result= task1.Result; // 获取Task<T>的Result值会阻塞当前线程,直到异步任务正常完成返回结果,或者传播异常信息返回 7 8 Console.WriteLine($"Main Ok ,CurrentThreadId:{Thread.CurrentThread.ManagedThreadId},是否线程池线程:{Thread.CurrentThread.IsThreadPoolThread}\r\n"); 9 Console.Read(); 10 } 11 12 public static async Task<string> TaskMethod0101(string taskName,double seconds) 13 { 14 Console.WriteLine($"await 之前的代码运行在调用异步方法的线程里,CurrentThreadId:{Thread.CurrentThread.ManagedThreadId},是否线程池线程:{Thread.CurrentThread.IsThreadPoolThread} \r\n"); 15 16 // 当运行到await所在行后,调用线程在这里会立即返回 17 await Task.Delay(TimeSpan.FromSeconds(seconds)); // 如果这里没有await,则这里不会异步等待而是继续同步运行await后面的代码 18 19 // 一般情况下当await异步等待的任务完成后,await之后的代码重新排队从线程池中申请可用工作线程继续执行 20 Console.WriteLine($"await之后的代码重新排队从线程池中申请可用工作线程继续执行,CurrentThreadId:{Thread.CurrentThread.ManagedThreadId},是否线程池线程:{Thread.CurrentThread.IsThreadPoolThread} \r\n"); 21 22 return $"{taskName} Complete"; 23 }
运行结果:
运行结果分析:
如果异步方法没有await修饰符,则调用线程(即Main方法所在的线程)会同步执行await之后的代码
当运行到await所在行后,调用线程在这里会立即返回,await等待的异步任务会被调度程序重新排队到线程池申请可用的工作线程中异步执行实例如下图: