在我的项目代码库中,我看到许多方法归结为以下代码:
public async Task<bool> MyAsyncFunction(string filePath)
{
byte[] fileBytes = await File.ReadAllBytesAsync(filePath);
bool succeeded = await UploadFileSomewhereAsync(fileBytes);
return succeeded;
}
我理解async/await对于前端代码中的非阻塞UI任务是有用的。我也明白async/await可以用来并行运行某些任务,如下面的代码所示:
public async Task<bool> MyAsyncFunction(string filePath)
{
Task<byte[]> fileBytesTask = File.ReadAllBytesAsync(filePath);
// do some other work that does not need the file byte array
byte[] fileBytes = await fileBytesTask;
bool succeeded = await UploadFileSomewhereAsync(fileBytes);
return succeeded;
}
然而,在第一个例子中,async/await模式有什么用呢?与简单地调用这些方法的同步版本相比,编写这样的代码有什么好处吗?我错过什么了吗?对Stephen Clearys的评论进行一点扩展
异步代码主要有两种用例:
- 对于UI应用程序,你不想在做一些缓慢的io操作时冻结你的UI,比如读取一个大文件,或者做一些进程密集型的事情。
- 对于服务器应用程序,您不希望在等待慢IO操作时消耗线程。许多服务器都是相当简单的数据库前端。如果您有1000个并发查询并且使用同步代码,那么您可能需要1000个正在等待的线程。线程使用一些资源,比如内存,当试图服务大量并发用户时,这会变得很浪费。
编写异步代码的旧风格有点难以使用,因为您需要手动跟踪在IO操作完成后需要完成的所有操作。Async/await通过让编译器完成困难的部分,从而在很大程度上避免了这种情况,让您编写的代码看起来像常规的顺序代码。
对async/await的批评是,有时使用同步方法更好。因此,您可能需要为本质上相同的代码编写两个版本。