C# 异步函数中为什么以及何时需要wait?

C# 异步函数中为什么以及何时需要wait?,c#,asynchronous,async-await,C#,Asynchronous,Async Await,我知道也有人问过类似的问题,但我正在与.net中异步编程的概念作斗争。作为一名web开发人员,我了解异步调用函数如何不会导致UI阻塞,您可以做其他事情。但现在我在另一边,编写一个C#WebAPI服务,从数据库中检索信息并进行一些计算。我将async关键字添加到函数头中,使控制器中的函数成为异步的,我天真地认为这将是函数头的结尾,但它告诉我需要在函数中使用wait关键字。所以我想出了如何做到这一点(我读了很多这一点),但我不明白为什么我需要这样做,以及什么时候。比如说,我有一个web方法,如下所示

我知道也有人问过类似的问题,但我正在与.net中异步编程的概念作斗争。作为一名web开发人员,我了解异步调用函数如何不会导致UI阻塞,您可以做其他事情。但现在我在另一边,编写一个C#WebAPI服务,从数据库中检索信息并进行一些计算。我将async关键字添加到函数头中,使控制器中的函数成为异步的,我天真地认为这将是函数头的结尾,但它告诉我需要在函数中使用wait关键字。所以我想出了如何做到这一点(我读了很多这一点),但我不明白为什么我需要这样做,以及什么时候。比如说,我有一个web方法,如下所示,它调用了另外两个函数,但只有一个用wait调用。那么糟糕吗?它只会在一段时间内不阻塞吗?然后,我做了另一个测试函数,它没有wait关键字,并且运行良好(底层代码)


我将尝试在不涉及技术问题的情况下进行区分。基本上,如果您关心返回值是什么。。等待。否则。。。你的电话。但没有等待,这只是一项任务

例如,我写了一个计算税收的函数,没有等待,我没有返回值,因此失败了。经过等待(这不是唯一的办法),我得到了答案,比如说
如果您仍有困难,请告诉我。

我将尝试在不涉及技术问题的情况下进行区分。基本上,如果您关心返回值是什么。。等待。否则。。。你的电话。但没有等待,这只是一项任务

例如,我写了一个计算税收的函数,没有等待,我没有返回值,因此失败了。经过等待(这不是唯一的办法),我得到了答案,比如说
如果您仍然卡住了,请告诉我。

在web应用程序端点(API端点、控制器操作等)的上下文中,不一定认为它“不阻塞UI”。相反,可以将其视为“不占用web服务器线程”。考虑一个Web服务,它使用磁盘或其他系统执行一些I/O。通过使这些I/O操作异步,web服务器可以在调用这些I/O操作时自由地接收/处理更多请求

您几乎总是在等待异步操作。只有当你真正知道自己在做什么的时候,你才不会这么做。当你的代码在这里写东西时,它在做什么,确保操作在进入下一行代码之前完成。这可能是件好事。特别是如果下一行代码需要异步操作执行的某些操作

如果控制器或API方法在内部调用异步操作,请等待它们。如果它不调用任何函数,那么它本身就不需要是异步的


*注意:很多时候,人们通常会天真地不等待异步操作,因为他们希望它是“点燃并忘记”的。记住“忘记”那一部分。“忘记”的意思是“我不在乎这个手术是否成功。”


有时候也可以。大多数时候不是这样。如果要确保操作结果,请等待。让顶层应用程序层担心UI。

在web应用程序端点(API端点、控制器操作等)的上下文中,不一定认为它“不阻塞UI”。相反,可以将其视为“不占用web服务器线程”。考虑一个Web服务,它使用磁盘或其他系统执行一些I/O。通过使这些I/O操作异步,web服务器可以在调用这些I/O操作时自由地接收/处理更多请求

您几乎总是在等待异步操作。只有当你真正知道自己在做什么的时候,你才不会这么做。当你的代码在这里写东西时,它在做什么,确保操作在进入下一行代码之前完成。这可能是件好事。特别是如果下一行代码需要异步操作执行的某些操作

如果控制器或API方法在内部调用异步操作,请等待它们。如果它不调用任何函数,那么它本身就不需要是异步的


*注意:很多时候,人们通常会天真地不等待异步操作,因为他们希望它是“点燃并忘记”的。记住“忘记”那一部分。“忘记”的意思是“我不在乎这个手术是否成功。”


有时候也可以。大多数时候不是这样。如果要确保操作结果,请等待。让顶层应用程序层为UI担心。

对于API调用,不必使用异步。默认情况下,它已经是断言,而不必受到影响。@Marceloveira我不太清楚您的意思,但如果API操作想要返回任务的值,您将希望等待它。我的意思是,该操作不一定必须是异步公共**异步任务**CalculateBMIAsync(对于API调用,不必使用异步。默认情况下,异步已经是断言,而不必受到影响。@Marceloveira我不太清楚您的意思,但如果API操作想要返回任务的值,您将需要等待它。我的意思是,该操作不必是异步的**异步任务**CalculateBMIAsync(在读了3遍之后…我有一个“啊哈”的时刻。我从来没有考虑过你可能不关心返回值的情况。在我的情况下,我总是关心,但现在我可以用David使用的术语来想一想人们可能“开火并忘记”的情况。在读了3遍之后…我有一个“啊哈”片刻。我从未考虑过你可能不关心回报值的情况。在我的情况下,我总是关心,但现在我可以想到人们可能“开火并忘记”的情况
[HttpPost]
public async Task<IHttpActionResult> CalculateBMIAsync([FromBody]MeasureInput patientData)
       {            
           string results = String.Empty;
           MeasureReturn returnVal = null;

           try
           {    
               string msgInvalid = await Translators.validatePatMonthXML(patientData);

               if (String.IsNullOrEmpty(msgInvalid))
               {
                   results = await measureProcessor.CalculateBMI(patientData);

               }
               else
                   return new BadRequestWithInfoResult(Translators.CreateErrorXML(new Exception(msgInvalid)));
           }
           catch (Exception ex)
           {
               return new BadRequestWithInfoResult(Translators.CreateErrorXML(ex));
           }

           return Ok<MeasureReturn>(returnVal);
       }
[HttpPost]
public async Task<IHttpActionResult> CalculateTest()
{           

    long d = 0;
    for (long i = 0; i < 2000000000; i++)
    {
        d = i;
    }

    string returnVal = d.ToString();

    return Ok(returnVal);
}
 $('#btn1').click(function () {
            console.log('Ajax request');
            $.ajax({
                url: 'http://localhost:53312/api/Measures/CalculateTest',
                type: 'POST',
                success: function (data) {
                    $('#result1').html('async request finished');
                }
            })
        });