异步/等待执行差异

本文关键字:执行 等待 异步 | 更新日期: 2023-09-27 17:59:08

我试图很好地掌握async/await,我想消除一些混乱。有人可以解释一下以下内容在执行方面的区别是什么:

// version 1
public Task Copy(string source, string destination) {
    return Task.Run(() => File.Copy(source, destination));
}
public async Task Test() {
    await Copy("test", "test2");    
    // do other stuff
}

和:

// version 2
public async Task Copy(string source, string destination) {
    await Task.Run(() => File.Copy(source, destination));
}
public async Task Test() {
    await Copy("test", "test2");
    // ...
}

它们是否产生相同的代码,为什么我要写一个而不是另一个?

异步/等待执行差异

首先,让我从两个代码相同的观点开始。

您的 version1 代码将仅创建一个"状态机",因为它仅在Test方法中包含 await。

您的 version2 代码将为CopyTest方法创建两个"状态机",这会增加一些开销。

我们为什么要使用async方法?简单只是为了使我们的代码可读,在处理"异步任务"时优雅。它使我们的代码更好地避免回调和延续等。

让我们分解一下Copy方法正在做什么,我们回答 质疑我们是否真的需要它async

Copy方法只是将调用委托给Task.Run,返回一个任务,该任务最终在File.Copy完成时完成。因此,这里的意图很明确,我们需要一个通知File.Copy完成的任务。此方法可以完成您需要的所有操作,无需将其async按预期工作。

那么,你什么时候需要async

当您需要在早期任务完成时执行一些代码时,您需要异步(延续(。

例:

public async Task Test() 
{
    await Copy("test", "test2");
    DoPostCopied(whatever);
    await DoPostCopied2();//Etc
}

只需反编译两个版本,即可验证async和非异步方法之间的这种差异。它太长了,不可读,所以我跳过了在这里发布它。

结论:仅在需要时使用async。在这种情况下,版本 1 更好,您应该更喜欢它而不是版本 2。