常见的异步方式async 和 await
之前研究过c#的async和await关键字,幕后干了什么,但是不知道为什么找不到相关资料了。现在重新研究一遍,顺便记录下来,方便以后查阅。
基础知识
async 关键字标注一个方法,该方法返回值是一个Task、或者Task<TResult>、void、包含GetAwaiter方法的类型。该方法通常包含一个await表达式。该表达式标注一个点,将被某个异步方法回跳到该点。并且,当前函数执行到该点,将立刻返回控制权给调用方。
以上描述了async方法想干的事情,至于如何实现,这里就不涉猎了。
个人见解
由此可以知道,async 和await关键字主要目的是为了控制异步线程的同步,让一个异步过程,表现得好像同步过程一样。
比如async 方法分n个任务去下载网页并进行处理:先await下载,然后立刻返回调用方,之后的处理就由异步线程完成下载后调用。这时候调用方可以继续执行它的任务,不过,如果调用方立刻就需要async的结果,那么应该就只能等待,不过大多数情况:他暂时不需要这个结果,那么就可以并行处理这些代码。
可见,并行性体现在await 上,如果await 点和最终的数据结果距离越远,那么并行度就越高。如果await的点越多,相信也会改善并行性。
资料显示,async 和await 关键字并不会创建线程,这是很关键的一点。他们只是创建了一个返回点,提供给需要他的线程使用。那么线程究竟是谁创建?注意await 表达式的组成,他需要一个Task,一个Task并不代表一定要创建线程,也可以是另一个async方法,但是层层包裹最里面的方法,很可能就是一个原生的Task,比如await Task.Run(()=>Thread.Sleep(0)); ,这个真正产生线程的语句,就会根据前面那些await点,逐个回调。
从这点来看,async 方法,未必就是一个异步方法,他在语义上更加贴近“非阻塞”, 当遇到阻塞操作,立刻用await定点返回,至于其他更深一层的解决手段,它就不关心了。这是程序员需要关心的,程序员需要用真正的创建线程代码,来完成异步操作(当然这一步可由库程序员完成)。
注意async的几个返回值类型,这代表了不同的使用场景。如果是void,说明客户端不关心数据同步问题,它只需要线程的控制权立刻返回。可以用在ui 等场合,如果是Task,客户端也不关心数据,但是它希望能够控制异步线程,这可能是对任务执行顺序有一定的要求。当然,最常见的是Task<TResult>。
综上,async和await并不是为了多任务而设计的,如果追求高并发,应该在async函数内部用Task好好设计一番。在使用async 和await的时候,只需要按照非阻塞的思路去编写代码就可以了,至于幕后怎么处理就交给真正的多线程代码创建者吧。
示范代码
static async Task RunTaskAsync(int step)
{
for(int i=0; i < step; i++)
{
await Task.Run(()=>Thread.Sleep(tmloop));//点是静态的,依次执行
Thread.Sleep(tm2);
}
Thread.Sleep(tm3);
} //客户端
Task tk= RunTaskAsync(step);
Thread.Sleep(tm1);//这一段是并行的,取max(函数,代码段)最大时间
tk.Wait( );//这里代表最终数据
为了达到高度并行,应该用真正的多线程代码:
static async Task RunTaskByParallelAsync(int step)
{
await Task.Run(()=>Parallel.For(0,step,
s=>{loop(tmloop);
loop(tm2);
}
));
loop(tm3);
}
并行编码方法
并行执行有几个方法,第一个是创建n个Task,一起启动。问题是怎么处理await点。每个task写一个await点是不行的,因为遇到第一个await就立刻返回,而不会开启所有任务并行执行。因此await不能随便放。那么如何为一组Task设定await点呢?可以通过Task.WhenAll 这个方法,他会等待一组Task执行完毕返回。
特定情况下,可以用Parallel.For 来开启一组任务,但是这个类并没有实现async模式,也就是它会阻塞当前线程,所以需要用一个Task来包裹它。
可见,非阻塞和并行不完全是一回事。
常见的异步方式async 和 await的更多相关文章
- 反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑) C#中缓存的使用 C#操作redis WPF 控件库——可拖动选项卡的TabControl 【Bootstrap系列】详解Bootstrap-table AutoFac event 和delegate的分别 常见的异步方式async 和 await C# Task用法 c#源码的执行过程
反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑) 背景介绍: 为了平衡社区成员的贡献和索取,一起帮引入了帮帮币.当用户积分(帮帮点)达到一定数额之后,就会“掉落”一定数量的“帮帮 ...
- .NET4.5 异步编程 async和await
msdn介绍:https://msdn.microsoft.com/zh-cn/library/hh191443.aspx 其实很简单,标记了async的方法为异步方法,从方法的左大括号开始同步执行, ...
- C#异步编程(async and await)及异步方法同步调用
1.什么是异步? 异步操作通常用于执行完成时间可能较长的任务,如打开大文件.连接远程计算机或查询数据库=异步操作在主应用程序线程以外的线程中执行.应用程序调用方法异步执行某个操作时,应用程序可在异步方 ...
- 彻底搞懂C#异步编程 async和await的原理
1.前提 熟练掌握Task并行编程. 2.用Task并行解释async和await异步 因为控制台有多线程操作的优化,因此这里选择winform来做示例. 测试代码如下所示: 有三个textbox,一 ...
- 异步编程- async和await
使用目的 避免阻塞主线程 提高程序响应能力 C#中使用 C# 中的 Async 和 Await 关键字是异步编程的核心. 疑惑 The async and await keywords don't c ...
- C#中的异步编程Async 和 Await
谈到C#中的异步编程,离不开Async和Await关键字 谈到异步编程,首先我们就要明白到底什么是异步编程. 平时我们的编程一般都是同步编程,所谓同步编程的意思,和我们平时说的同时做几件事情完全不同. ...
- 令人清爽的异步函数async、await
1.什么是async.await? async用于声明一个函数是异步的.而await从字面意思上是"等待"的意思,就是用于等待异步完成.并且await只能在async函数中使用; ...
- C#异步编程----async和await组合的写法
微软示例: private async void StartButton_Click(object sender, RoutedEventArgs e) { // ExampleMethodAsync ...
- .net异步编程async和await的讨论收获
微软官方描述: C# 5 引入了一种简便方法,即异步编程.此方法利用了 .NET Framework 4.5 及更高版本..NET Core 和 Windows 运行时中的异步支持. 编译器可执行开发 ...
随机推荐
- Spring Cloud Alibaba基础教程:Nacos的集群部署
继续说说生产环境的Nacos搭建,通过上一篇<Spring Cloud Alibaba基础教程:Nacos的数据持久化>的介绍,我们已经知道Nacos对配置信息的存储原理,在集群搭建的时候 ...
- swagger Failed to load Api definition 的问题
这个问题是由于Tomcat乱码问题导致的,修改server.xml文件的编码格式修改成UTF-8
- CesiumJS 添加会动的GIF
由于Cesium使用canvas渲染,如果使用billboard等加载gif图片只能渲染第一帧,导致动图不动.在Cesium的官方示例中找到一段代码可将HTML元素渲染到地图上,将gif以html元素 ...
- Windows下建立FTP服务器站点
环境 操作系统版本:Win7旗舰版64位系统 1.安装FTP组件 打开或关闭Windows功能,打开过程可能会比较慢,大概3.4分钟: 安装FTP组件.勾选Internet信息服务下的FTP服务器.F ...
- July 10th, 2018. Tuesday, Week 28th
Winning isn't everything, but wanting it is. 胜利并不能代表一切,但求胜心可以. From Arnold Palmer. Compared to this ...
- Gaussian Mixture Models and the EM algorithm汇总
Gaussian Mixture Models and the EM algorithm汇总 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 1. 漫谈 ...
- php实现中文字符串无乱码截取
在PHP开发中会经常用到字符串截取,有的时候字符串截取会出现乱码的情况,那么怎么解决这个问题呢,其实也很容易 首先我们要了解关于中英文占多少字节的问题. ASCII码:一个中文汉字占两个字节的空间. ...
- appium-desktop定位元素原理
初衷 最近在编写Android App自动化用例,其中元素定位相对来说耗费的时间比较长.我们都知道Appium-desktop拥有自己的录制功能,我们就在想是不是可以把录制功能跟我司的自动化框架(AT ...
- 如何接入银联“快速接入”产品API
引言:使用银联开放平台的用户或多或少都接触过产品API吧,那么大家对于“快速接入”产品API是否还会存在一些疑问呢?因为我之前对“快速接入”模糊不清,所以整理的一份详细的资料,里面梳理了“快速接入”产 ...
- 蓝牙协议中的SBC编解码原理和仿真
一.SBC的原理 SBC是subband codec的缩写,中文叫做次频带编码,也叫子带编码.其基本原理是把信号的频率分为若干子带,然后对每个子带进行编码,并根据每个子带的重要性及特点分配不同的位数( ...