为什么在等待它被认为是异步的同一行上调用一个方法?

时间:2016-05-16 01:53:25

标签: c# async-await

我正在查看http://www.dotnetperls.com/async上的示例,以便更好地了解异步/等待,但以下内容让我感到困惑:

我理解为什么以下示例被视为异步。调用 HandleFileAsync ,进行 Console.WriteLine 调用,然后等待 task 完成后再继续。

static async void ProcessDataAsync()
{
     // Start the HandleFile method.
     Task<int> task = HandleFileAsync("C:\\enable1.txt");

     // Control returns here before HandleFileAsync returns.
     // ... Prompt the user.
     Console.WriteLine("Please wait patiently " +
         "while I do something important.");

     // Wait for the HandleFile task to complete.
     // ... Display its results.
     int x = await task;
     Console.WriteLine("Count: " + x);
}

但是在以下示例中,我们等待 Task.Run 的调用,该 Task.Run 运行一个操作:

static async void Example()
{
     // This method runs asynchronously.
     int t = await Task.Run(() => Allocate());
     Console.WriteLine("Compute: " + t);
}

那么,如果我们等待在这里完成Task.Run,​​那究竟是异步发生了什么?我们认为只要我们等待后续任务的执行完成就会成为阻塞调用,在这种情况下,在同一行上调用它。

我错过了什么?

2 个答案:

答案 0 :(得分:9)

  

一旦我们等待后续任务的执行完成,我认为它会成为阻塞调用,在这种情况下,在同一行上调用它。我错过了什么?

你的信念是假的;这就是你所缺少的。 “await”意味着“现在返回,在我们异步等待时运行其他东西,当结果可用时,请回到这里。”

获取任务的结果会做您认为等待的事情。如果它只是同步获取任务的结果,我们就不必发明等待!它异步获取任务的结果。

虽然我们在这,但这个评论是错误的:

// Control returns here before HandleFileAsync returns.

怎么可能呢? HandleFileAsync返回了一个任务!如果HandleFileAsync没有返回,控件如何通过手头的任务来到达?当然它回来了。

这条评论具有误导性:

// Wait for the HandleFile task to complete.

应该异步等待以完成任务。通过异步等待,请记住,我们的意思是“现在返回,继续运行更多工作,当任务完成时,在此时恢复结果。”

如果我是你,我会找到更好的教程。

答案 1 :(得分:0)

究竟发生了什么异步? 考虑一下:

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    class Program
    {
        static volatile uint i;
        static uint Test()
        {
            Thread.Sleep(1000);
            i = 2; //uint.MaxValue;
            while (i-- > 0) { }
            return i;
        }

        static bool done;
        static async void Example()
        {
            var t = await Task.Run(() => Test());
            Console.WriteLine("result: " + t);
            done = true;
        }
        static void Main(string[] args)
        {
            Example();
            Console.WriteLine("wait: Control returns here before Example() returns ");
            while (!done) { }
            Console.WriteLine("done ");
        }
    }
}

Example();本身是异步发生的。 所以如果你删除while (!done) { }
程序在Example()完成之前退出 我希望这会有所帮助。