试图理解c#

时间:2016-04-03 13:30:16

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

我使用async关键字编写了一个方法,但无法理解它的结果,以及它无法正常工作的原因:

static async void ExampleWithValueReturned_Async(Stopwatch sw, SlowOperation opr1, SlowOperation opr2)
{
    Console.WriteLine("Started processing ASYNC. Start: {0}", sw.Elapsed);
    sw.Start();

    Console.WriteLine("2 Step0: {0}", sw.Elapsed);
    var sum1_2 = await Task<double>.Factory.StartNew(() => opr1.PerformSlowOperation(1, true));
    Console.WriteLine("2 Step1: {0}", sw.Elapsed);
    var sum2_2 = await Task<double>.Factory.StartNew(() => opr2.PerformSlowOperation(1, true));
    Console.WriteLine("2 Step2: {0}", sw.Elapsed);

    Console.WriteLine("Operation 1 gave sum: {0}", sum1_2.ToString("0.##"));
    Console.WriteLine("Operation 2 gave sum: {0}", sum2_2.ToString("0.##"));
    Console.WriteLine("Stopped processing ASYNC. Stop: {0}", sw.Elapsed);
    sw.Stop();

    sw.Reset();
    Console.WriteLine("");
}

由于PerformSlowOperation将并行运行,因此我希望它的运行速度是内联处理速度的两倍。我的期望是生成sum1_2和sum2_2将同时发生,而基于秒表日志的结果分析表明,两个值的处理方式与内联处理案例完全相同。两种情况下的总时间也相同。为什么会这样?

1 个答案:

答案 0 :(得分:5)

C#await关键字正好与单词所说的相同,它等待函数在继续执行下一行之前完成执行。如果您没有使用await关键字,那么它将在后台运行并继续执行其余代码,但是这不允许您对结果执行任何操作。

要并行运行这两个任务,您需要明确声明等待所有任务完成后再继续而不是等待每个任务。

Task t1 = Task<double>.Factory.StartNew(() => opr1.PerformSlowOperation(1, true));
Task t2 = Task<double>.Factory.StartNew(() => opr2.PerformSlowOperation(1, true));
await Task.WhenAll(t1,t2);
var sum1_2 = t1.Result;
var sum2_2 = t2.Result;

上面的代码将一直等到两个完成,然后并行运行它们,然后再继续使用其余的代码。

关键字存在的原因不是启用并行任务,而是让应用程序在执行其余代码之前等待单个异步方法完成。它在ASP.NET中非常有用,其中长时间运行的任务会浪费线程,使用await告诉ASP.NET它可以放弃对另一个请求的线程控制,直到前一个长时间运行的请求为止。任务完成然后当它完成时让它回来控制线程。