加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

async、await正确姿势

发布时间:2020-12-15 04:37:42 所属栏目:百科 来源:网络整理
导读:摘要 async、await是在C# 5.0之后引入的一种简化异步操作的方式。使用它们之后,可以使我们的编写异步操作更加方便快捷,维护以及阅读起来更方便。 一个例子 async、await虽然简化了我们编写异步方法。但也很容易让人产生误解。首先看一个例子: Task > AddA

摘要

async、await是在C# 5.0之后引入的一种简化异步操作的方式。使用它们之后,可以使我们的编写异步操作更加方便快捷,维护以及阅读起来更方便。

一个例子

async、await虽然简化了我们编写异步方法。但也很容易让人产生误解。首先看一个例子:

Task<> AddAsync( x, Task.Factory.StartNew(() => { x +

这种加了async、await叫不叫异步呢?答案肯定不是的。我们可以这样叫这种方法:加了async、await标记的同步方法。

再看下面的一个例子

原文:??

. (See "Return Types" section.) because the return statement returns an integer. Task<> HttpClient client = </span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt; GetStringAsync returns a Task<string>. That means that when you await the </span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt; task you'll get a string (urlContents). </span> Task<<span style="color: #0000ff;"&gt;string</span>> getStringTask = client.GetStringAsync(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;http://msdn.microsoft.com</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;); </span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt; You can do work here that doesn't rely on the string from GetStringAsync. </span>

<span style="color: #000000;"> DoIndependentWork();

</span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt; The await operator suspends AccessTheWebAsync.  
</span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt;  - AccessTheWebAsync can't continue until getStringTask is complete.  
</span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt;  - Meanwhile,control returns to the caller of AccessTheWebAsync.  
</span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt;  - Control resumes here when getStringTask is complete.   
</span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt;  - The await operator then retrieves the string result from getStringTask.  </span>
<span style="color: #0000ff;"&gt;string</span> urlContents = <span style="color: #0000ff;"&gt;await</span><span style="color: #000000;"&gt; getStringTask;  

</span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt; The return statement specifies an integer result.  
</span><span style="color: #008000;"&gt;//</span><span style="color: #008000;"&gt; Any methods that are awaiting AccessTheWebAsync retrieve the length value.  </span>
<span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; urlContents.Length;  

}

上面的方法GetStringAsync,如果不需要返回值,可以移步进行执行,然后会执行方法DoIndependentWork方法,知道await??getStringTask拿到GetStringAsync方法的返回值。

以下特征总结了使上一个示例成为异步方法的原因。

  • 方法签名包含?async?修饰符。

  • 按照约定,异步方法的名称以“Async”后缀结尾。

  • 返回类型为下列类型之一:

    • 如果你的方法有操作数为 TResult 类型的返回语句,则为?。

    • 如果你的方法没有返回语句或具有没有操作数的返回语句,则为?。

    • Void:如果要编写异步事件处理程序。

    • 包含?GetAwaiter?方法的其他任何类型(自 C# 7 起)。

    有关详细信息,请参见本主题后面的“返回类型和参数”。

  • 方法通常包含至少一个 await 表达式,该表达式标记一个点,在该点上,直到等待的异步操作完成方法才能继续。 同时,将方法挂起,并且控件返回到方法的调用方。 本主题的下一节将解释悬挂点发生的情况。

在异步方法中,可使用提供的关键字和类型来指示需要完成的操作,且编译器会完成其余操作,其中包括持续跟踪控件以挂起方法返回等待点时发生的情况。 一些常规流程(例如,循环和异常处理)在传统异步代码中处理起来可能很困难。 在异步方法中,元素的编写频率与同步解决方案相同且此问题得到解决。

上面的方法执行过程

关系图中的数值对应于以下步骤。

  1. 事件处理程序调用并等待?AccessTheWebAsync?异步方法。

  2. AccessTheWebAsync?可创建??实例并调用??异步方法以下载网站内容作为字符串。

  3. GetStringAsync?中发生了某种情况,该情况挂起了它的进程。 可能必须等待网站下载或一些其他阻止活动。 为避免阻止资源,GetStringAsync?会将控制权出让给其调用方?AccessTheWebAsync

    GetStringAsync?返回?,其中?TResult?为字符串,并且?AccessTheWebAsync?将任务分配给?getStringTask?变量。 该任务表示调用?GetStringAsync?的正在进行的进程,其中承诺当工作完成时产生实际字符串值。

  4. 由于尚未等待?getStringTask,因此,AccessTheWebAsync?可以继续执行不依赖于?GetStringAsync?得出的最终结果的其他工作。 该任务由对同步方法?DoIndependentWork的调用表示。

  5. DoIndependentWork?是完成其工作并返回其调用方的同步方法。

  6. AccessTheWebAsync?已用完工作,可以不受?getStringTask?的结果影响。 接下来,AccessTheWebAsync?需要计算并返回该下载字符串的长度,但该方法仅在具有字符串时才能计算该值。

    因此,AccessTheWebAsync?使用一个 await 运算符来挂起其进度,并把控制权交给调用?AccessTheWebAsync?的方法。?AccessTheWebAsync?将?Task?返回给调用方。 该任务表示对产生下载字符串长度的整数结果的一个承诺。

?总结

简单一句话,并不是所有的加了async和await关键字的方法就是异步方法。可以这样理解 await 的位置决定了到底是不是异步方法,如果直接await xxxAsync那么是挂起当前方法直到拿到返回值才会执行下面的逻辑,这样就是一种同步方法了。异步是类似这样的 代码块:

task t=

<span style="color: #0000ff;">await<span style="color: #000000;"> t;

<span style="color: #008000;">//<span style="color: #008000;">结束

参考文章

?这篇文章对async、await介绍的非常详细,不懂的可以参考这个。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读