我正在尝试使用Eric Lippert在2011年的C#中的例子来理解Asynchronous Programming - Easier Asynchronous Programming with the New Visual Studio Async CTP中异步编程的基础。
我已经为上一个代码示例中引用的方法填充了存根,我希望在命令行中看到的是:
Start obtain order
Finish obtain order
Start obtain ingredients
Start obtain recipe
Finish obtain ingredients
Finish obtain recipe
Start recipe prepare meal
Finish recipe prepare meal
Diner receives meal但是相反,我看到每个方法都是依次调用的--没有任何东西是异步的。
我的代码中有错误吗,或者我误解了它应该如何工作?
非常感谢您的指导。
namespace AsyncAwait
{
using System;
using System.Threading.Tasks;
internal class Program
{
internal class Order
{
}
internal class Ingredients
{
}
internal class Recipe
{
internal async Task<Meal> PrepareAsync(Ingredients ingredients)
{
Console.WriteLine("Start recipe prepare meal");
await Task.Delay(4 * 1000);
Console.WriteLine("Finish recipe prepare meal");
return new Meal();
}
}
internal class Meal
{
}
private class Diner
{
internal void Give(Meal meal)
{
Console.WriteLine("Diner receives meal");
}
}
async private static Task<Order>ObtainOrderAsync(Diner diner)
{
Console.WriteLine("Start obtain order");
await Task.Delay(3 * 1000);
Console.WriteLine("Finish obtain order");
return new Order();
}
async private static Task<Ingredients>ObtainIngredientsAsync(Order order)
{
Console.WriteLine("Start obtain ingredients");
await Task.Delay(2 * 1000);
Console.WriteLine("Finish obtain ingredients");
return new Ingredients();
}
async private static Task<Recipe>ObtainRecipeAsync(Order order)
{
Console.WriteLine("Start obtain recipe");
await Task.Delay(5 * 1000);
Console.WriteLine("Finish obtain recipe");
return new Recipe();
}
async private static void ServeBreakfast(Diner diner)
{
Order order = await ObtainOrderAsync(diner);
Ingredients ingredients = await ObtainIngredientsAsync(order);
Recipe recipe = await ObtainRecipeAsync(order);
Meal meal = await recipe.PrepareAsync(ingredients);
diner.Give(meal);
}
static void Main(string[] args)
{
Diner diner = new Diner();
ServeBreakfast(diner);
Console.ReadLine();
}
}
}发布于 2017-08-25 05:08:38
这些任务方法中的每一个都会返回一个可以进行await编辑的任务。当您调用xxxAsync方法时,您启动了异步操作,但当您在同一行上执行结果(即await )时,您是在告诉程序“在继续之前,我需要此方法的结果”。
我在您的示例中看到的唯一可以并行运行的方法是ObtainIngredientsAsync和ObtainRecipeAsync。所有其他方法都需要先前方法的结果。
如果您希望这些提到的方法并行运行,请先调用这两个方法而不使用await,然后在继续操作之前对它们执行await。
async private static void ServeBreakfast(Diner diner)
{
Order order = await ObtainOrderAsync(diner);
Task<Ingredients> ingredientsTask = ObtainIngredientsAsync(order);
Task<Recipe> recipeTask = ObtainRecipeAsync(order);
Ingredients ingredients = await ingredientsTask;
Recipe recipe = await recipeTask
Meal meal = await recipe.PrepareAsync(ingredients);
diner.Give(meal);
}发布于 2017-08-25 05:10:41
您正在等待每项任务,一个接一个:
Order order = await ObtainOrderAsync(diner);
Ingredients ingredients = await ObtainIngredientsAsync(order);
Recipe recipe = await ObtainRecipeAsync(order);
Meal meal = await recipe.PrepareAsync(ingredients);
diner.Give(meal);当您await一个任务时,您将停止该方法的执行,直到该任务完成。
因此,您正在为您的任务定义一个严格的逐个顺序:在前一个任务完成之前,您不会启动一个任务。
这里有一个例子,其中两个任务是并行完成的,这应该会给出您期望的输出。
为了(希望)让代码更清晰,我已经将所有的等待分解为创建任务和等待它们的单独语句。
async private static void ServeBreakfast(Diner diner)
{
// first task is to get the order
Task<Order> getOrder = ObtainOrderAsync(diner);
// we need to wait for the order, then we
// can get the ingredients and recipe in parallel
Order order = await getOrder;
// ### Change from your logic: Here we're starting two tasks in parallel. ###
Task<Ingredients> getIngredients = ObtainIngredientsAsync(order);
Task<Recipe> getRecipe = ObtainRecipeAsync(order);
// once we have both the above we can make the meal
Ingredients ingredients = await getIngredients;
Recipe recipe = await getRecipe;
Task<Meal> getMeal = recipe.PrepareAsync(ingredients);
// when the meal is ready, give it to the diner
diner.Give(await getMeal);
}https://stackoverflow.com/questions/45870729
复制相似问题