async和await
class Program { static void Main(string[] args) { //AwaitAsyncClass.NoReturnNoAwait(); //AwaitAsyncClass.NoReturn(); //{ // Task t = AwaitAsyncClass.NoReturnTask(); // Console.WriteLine($"Main Thread Task ManagedThreadId={Thread.CurrentThread.ManagedThreadId}"); // t.Wait();//主线程等待Task的完成 阻塞的 // await t;//await后的代码会由线程池的线程执行 非阻塞 //} { Task<long> t = AwaitAsyncClass.SumAsync(); Console.WriteLine($"Main Thread Task ManagedThreadId={Thread.CurrentThread.ManagedThreadId}"); long lResult = t.Result;//访问result 主线程等待Task的完成 t.Wait();//等价于上一行 Console.WriteLine(lResult); } Console.WriteLine($"Main Thread Task ManagedThreadId={Thread.CurrentThread.ManagedThreadId}"); Console.ReadLine(); } } class AwaitAsyncClass { /// <summary> /// 只有async没有await,会有个warn /// 跟普通方法没有区别 /// </summary> public static async void NoReturnNoAwait() { //主线程执行 Console.WriteLine($"NoReturnNoAwait Sleep before Task,ThreadId={Thread.CurrentThread.ManagedThreadId}"); Task task = Task.Run(() =>//启动新线程完成任务 { Console.WriteLine($"NoReturnNoAwait Sleep before,ThreadId={Thread.CurrentThread.ManagedThreadId}"); Thread.Sleep(3000); Console.WriteLine($"NoReturnNoAwait Sleep after,ThreadId={Thread.CurrentThread.ManagedThreadId}"); }); //主线程执行 Console.WriteLine($"NoReturnNoAwait Sleep after Task,ThreadId={Thread.CurrentThread.ManagedThreadId}"); } /// <summary> /// async/await /// 不能单独await /// await 只能放在task前面 /// 不推荐void返回值,使用Task来代替 /// Task和Task<T>能够使用await, Task.WhenAny, Task.WhenAll等方式组合使用。Async Void 不行 /// </summary> public static async void NoReturn() { //主线程执行 Console.WriteLine($"NoReturn Sleep before await,ThreadId={Thread.CurrentThread.ManagedThreadId}"); TaskFactory taskFactory = new TaskFactory(); Task task = taskFactory.StartNew(() => { Console.WriteLine($"NoReturn Sleep before,ThreadId={Thread.CurrentThread.ManagedThreadId}"); Thread.Sleep(3000); Console.WriteLine($"NoReturn Sleep after,ThreadId={Thread.CurrentThread.ManagedThreadId}"); }); //task.ContinueWith(t => //{ // Console.WriteLine($"NoReturn Sleep after await,ThreadId={Thread.CurrentThread.ManagedThreadId}"); //}); await task;//主线程到这里就返回了,执行主线程任务 Console.WriteLine($"NoReturn Sleep after await,ThreadId={Thread.CurrentThread.ManagedThreadId}"); //await 后面的代码 和task.ContinueWith() 中回调方法类似 //这个回调的线程是不确定的:可能是主线程 可能是子线程 也可能是其他线程 } /// <summary> /// 无返回值 async Task == async void /// Task和Task<T>能够使用await, Task.WhenAny, Task.WhenAll等方式组合使用。Async Void 不行 /// </summary> /// <returns></returns> public static async Task NoReturnTask() { //这里还是主线程的id Console.WriteLine($"NoReturnTask Sleep before await,ThreadId={Thread.CurrentThread.ManagedThreadId}"); Task task = Task.Run(() => { Console.WriteLine($"NoReturnTask Sleep before,ThreadId={Thread.CurrentThread.ManagedThreadId}"); Thread.Sleep(3000); Console.WriteLine($"NoReturnTask Sleep after,ThreadId={Thread.CurrentThread.ManagedThreadId}"); }); await task; Console.WriteLine($"NoReturnTask Sleep after await,ThreadId={Thread.CurrentThread.ManagedThreadId}"); //return new TaskFactory().StartNew(() => { }); //不能return 没有async才行 } /// <summary> /// 带返回值的Task /// 要使用返回值就一定要等子线程计算完毕 /// </summary> /// <returns>async 就只返回long</returns> public static async Task<long> SumAsync() { Console.WriteLine($"SumAsync 111 start ManagedThreadId={Thread.CurrentThread.ManagedThreadId}"); long result = 0; await Task.Run(() => { for (int k = 0; k < 10; k++) { Console.WriteLine($"SumAsync {k} await Task.Run ManagedThreadId={Thread.CurrentThread.ManagedThreadId}"); Thread.Sleep(1000); } for (long i = 0; i < 999_999_999; i++) { result += i; } }); Console.WriteLine($"SumFactory 111 end ManagedThreadId={Thread.CurrentThread.ManagedThreadId}"); return result; } }