等待直接或等待以后的区别

时间:2016-07-20 12:08:48

标签: c# asynchronous async-await

我无法找到有关实际差异的任何信息。

所以我一直做到以下几点:

public async Task<int> DoSomethingAsync()
{
    DoSomethingElse()
    var result = await GetValueAsync();
    var intValue = DoAnotherThing(result);
    return intValue;
}

await电话,然后直接使用它,但我最近看到一些帖子,人们正在做以下事情:

public async Task<int> DoSomethingAsync()
{    
    var task = GetValueAsync();
    DoSomethingElse()
    var result = await task;
    var intValue = DoAnotherThing(result);
    return intValue;
}

这是否意味着方法GetValueAsync正在启动它的执行,然后我们等待它的结果呢?或者它是否意味着它同步执行但仍然await能够执行?

5 个答案:

答案 0 :(得分:4)

当Damien_The_Unbeliever说这取决于实施时,他是对的。

DoSomethingAsyncB

在这种情况下,DoSomethingAsyncA将需要约5秒,其中GetValueAsync将需要~10。但是,如果您的 00:00:10:0161446 00:00:05:0032000 返回的值计算是从其他地方开始的,那么就没有区别了。

<强>更新 我纠正了答案中的错误。这是我机器的输出:

.leftBarButtonItem

答案 1 :(得分:3)

在此

public async Task<int> DoSomethingAsync()
{
    DoSomethingElse()
    var result = await GetValueAsync();
    var intValue = DoAnotherThing(result);
    return intValue;
}

这意味着当您在不执行任何其他代码的情况下尽快等待GetValueAsync的结果时。

以下代码表示:

public async Task<int> DoSomethingAsync()
{    
    var task = GetValueAsync();
    DoSomethingElse()
    var result = await task;
    var intValue = DoAnotherThing(result);
    return intValue;
}

在等待GetValueAsync完成它时调用GetValueAsync并执行DoSomethingElse,然后在完成后继续执行DoAnotherThing

答案 2 :(得分:2)

人们常常认为async-await是由几个线程完成的。通常情况并非如此。除非您启动其他线程,否则所有代码都由同一个线程执行。检查当前线程的ThreadId将显示此信息。

interview Eric Lippert explained async-await in a restaurant metaphor中。在中间某处搜索异步等待。

他解释说,如果一个厨师烤面包,他可以等到面包烤好或开始做其他事情,然后回来看看烤面包机是否完成烘烤。

在您的第二个DoSomethingAsync中也会发生同样的情况。将日期写入磁盘时,您的线程会将数据传递给磁盘写入程序。写入磁盘是一个相对缓慢的过程。线程不会等待写入日期,而是开始执行其他操作。当它完成其他操作后,线程将等待,直到磁盘写入完成写入磁盘。

这仅在磁盘写入可以在您的线程执行其他操作时继续写入时才有用。因此,您通常会在涉及硬件时看到异步函数,或者启动其他线程执行某些工作的进程。如果异步函数必须进行一些耗时的计算,那么使函数异步是没有用的,除非它启动另一个线程来进行计算。即使这样,这是否应该在异步函数内完成,或者调用者是否应该自由决定是让自己的线程进行计算还是启动不同的线程来执行此操作,这是值得怀疑的。

Another article that helped me to understand async-await by Stephen Cleary,这个网站的重要贡献者(再次感谢Stephen!)

答案 3 :(得分:1)

在第一个示例中,您不会在GetValueAsync()返回结果之前执行代码。

在第二个 - 您将在var task = GetValueAsync();var result = await task;之间执行代码 - 您将执行DoSomethingElse()

参见小例子:

    public static Task<int> DoLongOperationAsync()
    {
        return Task.Run(() => { Thread.Sleep(5000); return 5; }); // 5 seconds
    }


    public static async Task TestMethod()
    {
        var result = await DoLongOperationAsync();
        Console.WriteLine("Console");
        Console.WriteLine(result);
    }

    public static async Task TestMethod2()
    {
        var result = DoLongOperationAsync();
        Console.WriteLine("Console");
        Console.WriteLine(await result);
    }


    static async DoSomething()
    {
        await TestMethod(); // here you see some text in console only after 5 seconds

        await TestMethod2(); // here you see some text in console immediately and after 5 seconds you will see "5"

    }

答案 4 :(得分:0)

您只需将Task结果的要求推迟到第一次以这种方式实际使用的语句,这意味着在执行到达该语句时,任务可能已经异步设置了它的结果。