之前研究过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的更多相关文章

  1. 反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑) C#中缓存的使用 C#操作redis WPF 控件库——可拖动选项卡的TabControl 【Bootstrap系列】详解Bootstrap-table AutoFac event 和delegate的分别 常见的异步方式async 和 await C# Task用法 c#源码的执行过程

    反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑)   背景介绍: 为了平衡社区成员的贡献和索取,一起帮引入了帮帮币.当用户积分(帮帮点)达到一定数额之后,就会“掉落”一定数量的“帮帮 ...

  2. .NET4.5 异步编程 async和await

    msdn介绍:https://msdn.microsoft.com/zh-cn/library/hh191443.aspx 其实很简单,标记了async的方法为异步方法,从方法的左大括号开始同步执行, ...

  3. C#异步编程(async and await)及异步方法同步调用

    1.什么是异步? 异步操作通常用于执行完成时间可能较长的任务,如打开大文件.连接远程计算机或查询数据库=异步操作在主应用程序线程以外的线程中执行.应用程序调用方法异步执行某个操作时,应用程序可在异步方 ...

  4. 彻底搞懂C#异步编程 async和await的原理

    1.前提 熟练掌握Task并行编程. 2.用Task并行解释async和await异步 因为控制台有多线程操作的优化,因此这里选择winform来做示例. 测试代码如下所示: 有三个textbox,一 ...

  5. 异步编程- async和await

    使用目的 避免阻塞主线程 提高程序响应能力 C#中使用 C# 中的 Async 和 Await 关键字是异步编程的核心. 疑惑 The async and await keywords don't c ...

  6. C#中的异步编程Async 和 Await

    谈到C#中的异步编程,离不开Async和Await关键字 谈到异步编程,首先我们就要明白到底什么是异步编程. 平时我们的编程一般都是同步编程,所谓同步编程的意思,和我们平时说的同时做几件事情完全不同. ...

  7. 令人清爽的异步函数async、await

    1.什么是async.await? async用于声明一个函数是异步的.而await从字面意思上是"等待"的意思,就是用于等待异步完成.并且await只能在async函数中使用; ...

  8. C#异步编程----async和await组合的写法

    微软示例: private async void StartButton_Click(object sender, RoutedEventArgs e) { // ExampleMethodAsync ...

  9. .net异步编程async和await的讨论收获

    微软官方描述: C# 5 引入了一种简便方法,即异步编程.此方法利用了 .NET Framework 4.5 及更高版本..NET Core 和 Windows 运行时中的异步支持. 编译器可执行开发 ...

随机推荐

  1. pytest-allure-poco之allure全量详细用法

    allure简介 Allure Framework是一个灵活的轻量级多语言测试报告工具.貌似是目前最漂亮的一个报告工具 python版本及必要库或工具 python 3.7 pytest 4.3.1 ...

  2. 老司机心得之时间管理"入坑"

    长期以来,时间管理一直被认为是自我管理,团队管理,项目管理的既关键又基础的手段,就连笔者本人也一直在崇尚时间管理的理念. 但是这里要讲的,不是什么鬼神方法论.而主要是对长时间以来学习和实践时间管理的一 ...

  3. Android Gradle 依赖配置:implementation & api

    背景: Android Gradle plugin 3.0开始(对应Gradle版本 4.1及以上),原有的依赖配置类型compile已经被废弃,开始使用implementation.api和anno ...

  4. WPF TextBox 正则验证 大于等于0 小于等于1 的两位小数

    正则:^(0\.\d+|[1-9][0-9]|1)$ TextBox绑定正则验证 <TextBox x:Name="txb"   MaxLength="6" ...

  5. [PHP] sys_get_temp_dir()和tempnam()函数报错与环境变量的配置问题

    1.项目运行过程中遇到个问题,保存临时文件时,一直返回false 2.根据经验这个是在/tmp目录下建立临时文件,所以检查了一遍权限问题,发现权限没有问题 3.查出sys_get_temp_dir() ...

  6. Web前端-Vue.js必备框架(五)

    Web前端-Vue.js必备框架(五) 页面组件,商品列表组件,详情组件,购物车清单组件,结算页组件,订单详情组件,订单列表组件. vue-router 路由 vuex 组件集中管理 webpack ...

  7. 免费开源ERP-成功案例分析(1)

    Odoo用户案例 Odoo用户概要 关于Odoo全球的用户,我们来看一些数据: Odoo目前全球有300万使用者 Odoo系统上每天新创建的数据库超过1000个 Odoo和Word.Excel.Pow ...

  8. 6.使用桌面版AI伴侣或手机版AI伴侣实时预览编程效果

    1.根据自己系统下载对应版本AI伴侣,最好解压到D盘根目录. 运行ailaunch.bat ,可以启动原本自带的2.46版AI伴侣.运行AI伴侣247.bat可以启动汉化2.47版的AI伴侣.并且默认 ...

  9. AI应用开发实战 - 定制化视觉服务的使用

    AI应用开发实战 - 定制化视觉服务的使用 本篇教程的目标是学会使用定制化视觉服务,并能在UWP应用中集成定制化视觉服务模型. 前一篇:AI应用开发实战 - 手写识别应用入门 建议和反馈,请发送到 h ...

  10. vue 过滤器 基本用法

    使用地点:双花括号插值和v-bind表达式. <div id="app"> <p>{{ message|capitalize}}</p> < ...