直接贴出代码:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace AsyncBreakfast
{
internal class Bacon { }
internal class Coffee { }
internal class Egg { }
internal class Juice { }
internal class Toast { }
class Program
{
public static async Task Run()
{
Coffee cup = PourCoffee();
Console.WriteLine("咖啡做好了");
var eggsTask = FryEggsAsync(2);
var baconTask = FryBaconAsync(3);
var toastTask = MakeToastWithButterAndJamAsync(2);
Juice oj = PourOJ();
Console.WriteLine("橙汁倒好了");
var breakfastTasks = new List<Task> { eggsTask, baconTask, toastTask };
while (breakfastTasks.Count > 0)
{
Task finishedTask = await Task.WhenAny(breakfastTasks);
if (finishedTask == eggsTask)
{
Console.WriteLine("鸡蛋做好了");
}
else if (finishedTask == baconTask)
{
Console.WriteLine("培根做好了");
}
else if (finishedTask == toastTask)
{
Console.WriteLine("面包做好了");
}
breakfastTasks.Remove(finishedTask);
}
Console.WriteLine("完美的一顿早餐!");
}
static async Task<Toast> MakeToastWithButterAndJamAsync(int number)
{
var toast = await ToastBreadAsync(number);
ApplyButter(toast);
ApplyJam(toast);
return toast;
}
private static Juice PourOJ()
{
Console.WriteLine("倒一杯橙汁");
return new Juice();
}
private static void ApplyJam(Toast toast) =>
Console.WriteLine("往面包上加点果酱");
private static void ApplyButter(Toast toast) =>
Console.WriteLine("往面包上加点奶油");
private static async Task<Toast> ToastBreadAsync(int slices)
{
for (int slice = 0; slice < slices; slice++)
{
Console.WriteLine("把一片面包放进烤面包机");
}
Console.WriteLine("开始烤面包...");
await Task.Delay(15000);
Console.WriteLine("从面包机里拿出面包");
return new Toast();
}
private static async Task<Bacon> FryBaconAsync(int slices)
{
Console.WriteLine($"将 {slices} 片培根放到平底锅中");
Console.WriteLine("先将一面煎至金黄...");
await Task.Delay(10000);
for (int slice = 0; slice < slices; slice++)
{
Console.WriteLine("将培根翻一边");
}
Console.WriteLine("将另一面煎至金黄...");
await Task.Delay(10000);
Console.WriteLine("把煎好的培根装盘");
return new Bacon();
}
private static async Task<Egg> FryEggsAsync(int howMany)
{
Console.WriteLine("热锅准备煎蛋");
await Task.Delay(3000);
Console.WriteLine($"打 {howMany} 个鸡蛋到碗里...");
Console.WriteLine("煎蛋中 ...");
await Task.Delay(5000);
Console.WriteLine("将鸡蛋装盘");
return new Egg();
}
private static Coffee PourCoffee()
{
Console.WriteLine("正在制作咖啡...");
return new Coffee();
}
}
}
在Main函数中异步调用:
using System;
using System.Collections;
using System.Threading.Tasks;
public sealed class Program
{
public static async Task Main()
{
await AsyncBreakfast.Program.Run();
}
}
可以清楚的看到控制台的执行结果:
总结:
通过async关键字将方法声明为异步方法,在遇到await关键字前会先执行方法内的同步代码,遇到await后跳出去执行方法外的同步代码,异步执行await的代码。
等到await代码执行完毕,继续执行await后面的同步代码。
异步方法会返回一个Task实例,可以通过Task的WhenAny方法监听Task是否执行完毕。