繁体   English   中英

不确定在异步方法中的哪里使用await运算符

[英]Not sure where to use an await operator in an async method

在阅读了很多有关异步/等待的内容之后,我仍然不确定在异步方法中在哪里使用等待操作符:

    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种方法创建一个异步版本并像这样调用吗?

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

还是应该仅使第一个异步?

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

有什么区别?

我仍然不确定我的异步方法中在哪里使用await运算符

您从错误的角度来解决问题。

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

基于名称“ Find”,“ SearchForAppointments和“ SomeCalculation”,我怀疑FindSearchForAppointments是基于I / O的,可能会访问数据库,而SomeCalculation只是在进行一些CPU计算。

但是暂时不要将“ Find更改为“ FindAsync 这仍然是错误的方式。 正确的方法是从最低的 API开始,因此无论Find最终做什么I / O。 例如,如果这是一个EF查询,则 Find使用EF6异步方法。 然后Find应该成为FindAsync ,这应该推动DailyScheduleDailyScheduleAsync ,这将导致它的调用者成为异步等就是这样的方式async要长。

每个async方法调用都需要await ,因此每个方法调用都会释放线程,因此不会引起阻塞。 因此,在您的情况下,这是您应该如何做:

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

正如VSG24说,你应该等待能够期待已久的 ,这是因为这将有助于你保持主线程从任何长时间运行的任务免费每个调用-这是,例如,从互联网上下载的数据的任务,从而节省任务使用I / O等将数据存储到磁盘。问题在于,每当您必须执行长时间运行的任务时,它总是会冻结UI。 为了克服这个问题,使用了异步模式,因此异步/等待允许您创建一个函数,该函数在后台执行长时间运行的任务,并且主线程与用户保持联系。

我仍然不确定我的异步方法中在哪里使用await运算符

直觉是,可以等待每个以Async结尾的函数(前提是它们的签名也匹配以下内容),并且它们返回TaskTask<T> 然后可以使用返回void的函数来等待它们-您不能等待void 因此,对于需要较长响应时间的功能,您应该在那里申请等待。 我个人的观点是,应该等待一个可能花费超过1秒的功能-因为那是设备上的1秒,也许您的客户端必须等待5秒,或更糟的是10秒。 他们只是要关闭应用程序然后走开,说, 这不起作用!

好吧,如果其中之一非常快,就不需要异步了,对吧?

快速以什么方式? 不要忘记,您的客户可能没有非常快的计算机,并且肯定会受到冻结应用程序的困扰。 因此,他们很喜欢,并且总是在等待功能。

有什么区别?

所不同的是,在最后一个代码示例中,将仅等待第一个调用,而其他调用将同步执行。 Visual Studio还将通过在代码上方提供绿色的波浪线(将鼠标悬停在该代码上方)来向您解释此部分。 这就是为什么,您应该尽可能等待每个异步调用。

提示 :如果需要执行该函数中的过程,例如在启动应用程序之前加载所有数据,则应避免使用异步/等待模式,而应使用同步方法下载数据并执行其他任务。 因此,这完全取决于您在做什么,而不是文档说的话。 :-)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM