不确定在异步方法的什么地方使用await操作符

本文关键字:await 操作符 什么地方 异步方法 不确定 | 更新日期: 2023-09-27 18:15:21

在阅读了大量关于async/await的内容后,我仍然不确定在async方法中应该在哪里使用await操作符:

    public async Task<IActionResult> DailySchedule(int professionalId, DateTime date)
    {
        var professional = professionalServices.Find(professionalId);            
        var appointments = scheduleService.SearchForAppointments(date, professional);
        appointments = scheduleService.SomeCalculation(appointments);
        return PartialView(appointments);
    }

我应该为所有3个方法创建一个async版本并像这样调用吗?

        var professional = await professionalServices.FindAsync(professionalId);            
        var appointments = await scheduleService.SearchForAppointmentsAsync(date, professional);
        appointments = await scheduleService.SomeCalculationAsync(appointments);

还是我应该让async只在第一个?

        var professional = await professionalServices.FindAsync(professionalId);            
        var appointments = scheduleService.SearchForAppointments(date, professional);
        appointments = scheduleService.SomeCalculation(appointments);

有什么区别?

不确定在异步方法的什么地方使用await操作符

我仍然不确定在async方法中我在哪里使用await操作符

你从错误的角度来看待这个问题。

转换为async时要更改的第一件事是最低级API调用。有一些操作自然是异步的——特别是I/O操作。其他操作自然是同步的——例如,CPU代码。

根据名称"Find","SearchForAppointments"answers"someecalculation",我怀疑FindSearchForAppointments是基于I/o的,可能会命中数据库,而SomeCalculation只是做一些CPU计算。

但是不要把Find改成FindAsync。还是走错方向了。正确的方法是从最低的 API开始,所以无论Find最终做什么I/O。例如,如果这是一个EF查询,那么在 Find中使用EF6异步方法。然后Find应该变成FindAsync,这应该驱动DailySchedule变成DailyScheduleAsync,这导致它的调用者变成异步的,等等。这就是async应该成长的方式

正如VSG24所说,您应该等待每个可以等待的调用,这是因为这将帮助您保持主线程免于任何长时间运行的任务—例如,从互联网下载数据的任务,使用I/O将数据保存到磁盘的任务等。问题是,每当你需要执行长时间运行的任务时,它总是会冻结UI。为了克服这个问题,使用了异步模式,因此这个async/await允许您创建一个在后台执行长时间运行任务的函数,并且主线程保持与用户通信。

我仍然不确定在async方法中我在哪里使用await操作符

直觉是,每个以Async结尾的函数都可以等待(如果它们的签名也匹配,如下所示),并且它们返回TaskTask<T>。然后可以使用返回void —你不能等待void。对于需要更长的时间来响应的函数,你应该在那里应用await。我个人的观点是,对于可能耗时超过1秒的函数,应该等待—因为这在你的设备上是1秒,也许你的客户端需要等待5秒,或者更糟糕的是10秒。他们只会关闭应用程序,然后走开,说:它不工作!.

好的,如果其中一个非常非常快,它不需要异步,对吧?

以什么方式快速?不要忘记,您的客户可能没有非常非常快的机器,他们肯定会受到应用程序冻结的影响。所以他们帮了忙,总是等待函数。

有什么区别?

不同之处在于,在上一个代码示例中,只有第一个调用将被等待,其他调用将同步执行。Visual Studio还将通过在代码下方提供绿色的弯弯曲曲的线条向您解释这部分内容,您可以将鼠标悬停在代码上方看到这些线条。这就是为什么在可能的情况下,您应该等待每个异步调用。

提示:如果函数中的过程是必需的,例如在启动应用程序之前加载所有数据,那么您应该避免async/await模式,而使用同步方法来下载数据并执行其他任务。所以这完全取决于你在做什么,而不是文件上说什么。: -)

每个async方法调用都需要被await调用,这样每个方法调用都会释放线程,从而不会导致阻塞。因此,在您的情况下,您应该这样做:

var professional = await professionalServices.FindAsync(professionalId);            
var appointments = await scheduleService.SearchForAppointmentsasync(date, professional);
appointments = await scheduleService.SomeCalculationAsync(appointments);