【问题标题】:Why is an explicit Task variable required to get Tasks to run in parallel?为什么要让任务并行运行需要显式任务变量?
【发布时间】:2019-09-16 09:14:05
【问题描述】:

我正在尝试使用 await 使一些数据库数据检索任务并行运行。出于某种原因,它仅在我显式创建 Task 变量时才有效,并且如果我直接等待返回这些 Tasks 的方法则不起作用。

我在下面的控制台应用中有一个问题示例:

class Program
{
    static async Task Main(string[] args)
    {
        //This runs sequentially
        await Write("Task 1");
        await Write("Task 2");
        await Write("Task 3");


        //This runs in parallel
        var t1 = Write("Task 1");
        var t2 = Write("Task 2");
        var t3 = Write("Task 3");
        await t1;
        await t2;
        await t3;

        Console.ReadKey();
    }

    static async Task Write(string text)
    {
        Console.WriteLine($"Start - {text}");
        await Task.Delay(1000);
        Console.WriteLine($"End - {text}");
    }
}

我希望这两种方法产生完全相同的结果。

【问题讨论】:

  • 因为Task可以在创建时启动,所以在等待之前。在您的第一个示例中,您按等待创建它。
  • 您正在按顺序运行它们。使用Task.WhenAll
  • await Write("Task 1"); 说“送我的一个孩子去商店,等他们回来”。 var t1 = Write("Task 1"); var t2 = Write("Task 2"); var t3 = Write("Task 3"); await t1; await t2; await t3; 说“把三个孩子都送到商店,等我送的第一个回来(然后等第二个,再等第三个)”。
  • 来自文档:“await 运算符暂停对封闭异步方法的评估,直到其操作数表示的异步操作完成”(docs.microsoft.com/en-us/dotnet/csharp/language-reference/…)。
  • 我怀疑你的意思是await Task.WhenAll(Write("Task 1"), Write("Task 2"), Write("Task 3"));

标签: c# parallel-processing async-await task


【解决方案1】:

TAP pattern 指定任务返回“热”,即进行中。 await will pause the current method until its argument completes.

因此,此代码将调用Write,它返回一个正在进行的任务。 await 然后暂停当前方法,直到该任务完成:

await Write("Task 1");

或者,此代码将调用Write,它返回一个正在进行的任务。然后将该任务放入一个变量中。由于没有await,所以方法没有暂停:

var t1 = Write("Task 1");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多