C#异步编程中Task.WhenAny泛型任务使用疑问
关于Task.WhenAny非泛型重载的解惑
先明确Task.WhenAny非泛型重载的核心行为:当你传入包含泛型Task<T>(比如Task<Egg>、Task<Bacon>)的List<Task>时,它确实返回Task<Task>——外层的Task代表"WhenAny判断哪个任务先完成"这个操作本身的完成状态,而它的结果就是第一个完成的原始任务实例(也就是你传入的eggsTask/baconTask/toastTask中的某一个)。
那代码里Task finishedTask = await Task.WhenAny(breakfastTasks);这行为什么是对的?await关键字会自动解包外层的Task<Task>,直接拿到它的结果值——也就是那个最先完成的原始Task对象(可能是Task<Egg>、Task<Bacon>这类泛型任务),所以这里用Task类型接收完全合理。
你疑惑的"泛型Task完成后应返回对应实体"没错,但Task.WhenAny的设计初衷是告诉你哪个任务先完成,而非直接返回该任务的结果。如果要获取具体的实体对象,需要对拿到的finishedTask再做一次await(或访问Result属性,推荐用await更安全),比如:
if (finishedTask is Task<Egg> completedEggTask) { Egg cookedEggs = await completedEggTask; // 处理煮熟的鸡蛋 }
举个贴合你场景的完整逻辑片段:
List<Task> breakfastTasks = new List<Task> { eggsTask, baconTask, toastTask }; while (breakfastTasks.Count > 0) { Task finishedTask = await Task.WhenAny(breakfastTasks); breakfastTasks.Remove(finishedTask); // 根据任务实际类型获取结果并处理 switch (finishedTask) { case Task<Egg> eggTask: Egg eggs = await eggTask; Console.WriteLine($"鸡蛋已准备好:{eggs.Doneness}"); break; case Task<Bacon> baconTask: Bacon bacon = await baconTask; Console.WriteLine($"培根已煎好:{bacon.Crispiness}"); break; case Task<Toast> toastTask: Toast toast = await toastTask; Console.WriteLine($"吐司已烤好:{toast.BrownLevel}"); break; } }
内容的提问来源于stack exchange,提问作者Deva Raja
相关产品推荐
相关产品推荐

