使用Async和Await的异步编程

    技术2022-07-12  82

    遇到await后,后序代码由新线程接管,即操作开始异步。 官方文档

    简易版

    不阻塞主线程

    class Program { static void Main(string[] args) { Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}"); Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}:{SayAsync().Status}"); Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}"); Console.ReadKey(true); } public static async Task<string> SayAsync() { Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}_SayAsync"); var s = await Task<string>.Run(async () => { await Task.Delay(TimeSpan.FromSeconds(2)); Console.WriteLine("---------------两秒后----------------"); Console.WriteLine($"子线程{Thread.CurrentThread.ManagedThreadId}"); return "vvull"; }); Console.WriteLine($"子线程{Thread.CurrentThread.ManagedThreadId}:{s}"); Console.WriteLine($"子线程{Thread.CurrentThread.ManagedThreadId}"); return s; } }

    阻塞主线程

    class Program { static void Main(string[] args) { Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}"); Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}:{SayAsync().Result}");//阻塞主线程 Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}"); Console.ReadKey(true); } public static async Task<string> SayAsync() { Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}_SayAsync"); var s = await Task<string>.Run(async () => { await Task.Delay(TimeSpan.FromSeconds(2)); Console.WriteLine("---------------两秒后----------------"); Console.WriteLine($"子线程{Thread.CurrentThread.ManagedThreadId}"); return "vvull"; }); Console.WriteLine($"子线程{Thread.CurrentThread.ManagedThreadId}:{s}"); Console.WriteLine($"子线程{Thread.CurrentThread.ManagedThreadId}"); return s; } }

    进阶版

    class Program { static void Main(string[] args) { Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->主线程"); giaoAsync(); Thread.Sleep(3000); Console.WriteLine("---------------三秒后----------------"); Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->主线程"); Console.ReadKey(); } static async Task giaoAsync() { Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->giao"); //Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->giao:{await SayAsync()}");//本句以后由新线程接管 //Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->giao*"); var s = await SayAsync();//由新线程接管 Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->giao**_{s}"); Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->giao**"); var ss = await SayAsync();//由新线程接管 Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->giao***_{ss}"); Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->giao***"); } public static async Task<string> SayAsync() { Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->SayAsync"); var s = await Task<string>.Run(async () => { Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->SayAsync*"); await Task.Delay(TimeSpan.FromSeconds(2)); Console.WriteLine("---------------两秒后----------------"); Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->SayAsync**"); return "vvull"; }); Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->SayAsync**_{s}"); Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->SayAsync**"); return s; } }

    官方例子魔改

    using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; namespace AsyncBreakfast { class Program { static async Task Main(string[] args) { Coffee cup = PourCoffee(); Console.WriteLine("coffee is ready"); Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->线程*"); var eggsTask = FryEggsAsync(2); var baconTask = FryBaconAsync(3); var toastTask = MakeToastWithButterAndJamAsync(2); Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->线程*"); var breakfastTasks = new List<Task> { eggsTask, baconTask, toastTask }; while (breakfastTasks.Count > 0) { Task finishedTask = await Task.WhenAny(breakfastTasks); Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->线程**"); if (finishedTask == eggsTask) { Console.WriteLine("eggs are ready"); } else if (finishedTask == baconTask) { Console.WriteLine("bacon is ready"); } else if (finishedTask == toastTask) { Console.WriteLine("toast is ready"); } breakfastTasks.Remove(finishedTask); Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->线程**"); } Juice oj = PourOJ(); Console.WriteLine("oj is ready"); Console.WriteLine("Breakfast is ready!"); Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->线程***"); Console.ReadKey(); } static async Task<Toast> MakeToastWithButterAndJamAsync(int number) { Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->线程*"); var toast = await ToastBreadAsync(number); Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->Toast线程"); ApplyButter(toast); ApplyJam(toast); return toast; } private static Juice PourOJ() { Console.WriteLine("Pouring orange juice"); return new Juice(); } private static void ApplyJam(Toast toast) => Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->Toast线程 " + "Putting jam on the toast"); private static void ApplyButter(Toast toast) => Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->Toast线程 " + "Putting butter on the toast"); private static async Task<Toast> ToastBreadAsync(int slices) { Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->线程*"); for (int slice = 0; slice < slices; slice++) { Console.WriteLine("Putting a slice of bread in the toaster"); } Console.WriteLine("Start toasting..."); await Task.Delay(3000); Console.WriteLine("--------Toast三秒后--------"); Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->Toast线程"); Console.WriteLine("Remove toast from toaster"); return new Toast(); } private static async Task<Bacon> FryBaconAsync(int slices) { Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->线程*"); Console.WriteLine($"putting {slices} slices of bacon in the pan"); Console.WriteLine("cooking first side of bacon..."); await Task.Delay(3000); Console.WriteLine("--------Bacon三秒后--------"); for (int slice = 0; slice < slices; slice++) { Console.WriteLine("flipping a slice of bacon"); } Console.WriteLine("cooking the second side of bacon..."); Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->Bacon线程*"); await Task.Delay(3000); Console.WriteLine("--------Bacon第二次三秒后--------"); Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->Bacon线程**"); Console.WriteLine("Put bacon on plate"); return new Bacon(); } private static async Task<Egg> FryEggsAsync(int howMany) { Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->线程*"); Console.WriteLine("Warming the egg pan..."); await Task.Delay(3000); Console.WriteLine("--------Eggs三秒后--------"); Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->Eggs线程*"); Console.WriteLine($"cracking {howMany} eggs"); Console.WriteLine("cooking the eggs ..."); await Task.Delay(3000); Console.WriteLine("--------Eggs第二次三秒后--------"); Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->Eggs线程**"); Console.WriteLine("Put eggs on plate"); return new Egg(); } private static Coffee PourCoffee() { Console.WriteLine("Pouring coffee"); return new Coffee(); } } class Egg { } class Toast { } class Juice { } class Bacon { } class Coffee { } }
    Processed: 0.019, SQL: 9