async、await正确姿势

前端之家收集整理的这篇文章主要介绍了async、await正确姿势前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

摘要

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方法的返回值。

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

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

上面的方法执行过程

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

  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介绍的非常详细,不懂的可以参考这个。

猜你在找的C#相关文章