对异步CTP感兴趣有很多原因。异步CTP使异步编程比以前更加容易了。它虽然没有Rx强大,但是更容易学。异步CTP介绍了两个新的关键字,async和await。异步方法(或Lambda表达式)必须返回void,Task或Task<TResult>。这篇文章不是介绍异步CTP的,因为网上有很多这样的文章。这篇文章的目的是把程序员开始使用Async CTP遇到的一些常见问题集中起来。

推断返回类型

当从异步方法返回一个值的时候,此方法体直接返回这个值,但该方法本身被声明为返回一个Task<TResult>。当声明一个返回甲类型的方法却必须返回一个乙类型时,就有点“断连”了。

// 实际语法
public async Task<int> GetValue()
{
await TaskEx.Delay();
return ; //返回类型是 "int", 而不是"Task<int>"
}

问题来了:为什么我不能这么写?

// 假想语法
public async int GetValue()
{
await TaskEx.Delay();
return ; // 返回类型是 "int"
}
思考:该方法如何如何照顾调用者呢?异步方法必须返回一个实际结果类型Task<TResult>的值。因此,GetValue方法会出现返回Task<TResult>的智能提示(在对象浏览器,Reflector等中也是这样的)。
 
在设计之初,推断返回类型已经被考虑到了,但该设计团队已经推断出在异步方法中保持这种“断连”比在代码基上扩大这种“断连”更好。如今这种“断连”仍存在,但比以前更小了。该设计团队的共识是一致的方法签名更佳。
思考:async void 和async Task有什么区别?
一个async Task方法就像任何其他的异步操作一样,只是没有返回值。一个async void方法扮演一种高级操作。async Task方法可能被组合进其他使用using await的异步方法。async void方法可能被用作一个事件句柄。async void方法也有其他重要的属性:在ASP.NET上下文中,它通知web服务器直到它返回,页面才完成。
 
推断返回类型会移除async void 和async Task间的区别:要么所有的异步方法是async void(阻止可组合性),要么都是async Task(阻止它们来自事件句柄,同时对ASP.NET要有一个可选择的方案)。

异步返回

 
在方法声明返回类型和方法体返回的类型之间仍有“断连”。该设计团队的另一个建议是:给return添加一个关键字来指示return返回的值,但这个也确实没有返回什么,如下所示:
// 假想语法
public async Task<int> GetValue()
{
await TaskEx.Delay();
async return ; // "async return" 意味着值被包装在Task中
}
思考:将大量的代码从同步转为异步。

async return关键字也被考虑到了,但并没有足够的说服力。当把一些同步代码转成异步代码时,这尤其正确。强制人们给每个return语句添加asynchronous就好像是“不必要的忙碌”。比较而言,习惯于“断连”更容易。

推断“async”

async关键字必须用在使用了await关键字的方法上。然而,如果把async用在了一个没有使用await的方法上,也会收到一个警告。

问题:为什么async不能根据await的存在推断出来?

//假想语法
public Task<int> GetValue()
{
// "await" 的存在暗示这是一个 "async" 方法.
await TaskEx.Delay();
return ;
}

思考:向后兼容性和代码可读性

单字的await关键字具有太大的打破变化。在异步方法上的多字await(如await for)或一个关键字之间的选择,只是在那个方法内部启用await关键字。很明显,使用async标记方法让人类和计算机分析起来更容易,因此设计团队决定使用async/await对。

推断“await”

问题:既然显示包括async有意义(看上面),为什么await不能根据async的存在推断出来呢?

// 假想语法
public async Task<int> GetValue()
{
// 暗示有"await",因为这是一个 "async" 方法.
TaskEx.Delay();
return ;
}

思考:异步操作的并行组合。

乍一看,推断await推断似乎简化了基本的异步操作。只要所有的等待可以按序列(如一个操作等待,然后另一个,再然后另一个)完成,这个就能很好的工作。然而,当有人考虑并行组合的时候,它崩溃了。

异步CTP中的并行组合使用TaskEx.WhenAny 和TaskEx.WhenAll方法。这有一个简单的例子,这个方法立即开始了两个操作,并且等待它们完成。

// 实际语法
public async Task<int> GetValue()
{
// 异步检索两个部分的值
// 注意此时它们是没有等待的“not await”
Task<int> part1 = GetValuePart1();
Task<int> part2 = GetValuePart2(); // 等待它们的值到达。
await TaskEx.WhenAll(part1, part2); // 计算我们的结果
int value1 = await part1; // 实际上没有等待
int value2 = await part2; //实际上没有等待
return value1 + value2;
}

为了处理并行组合,我们必须有能力说我们将不会await一个表达式。

异步CTP(Async CTP)为什么那样工作?的更多相关文章

  1. .net 反射访问私有变量和私有方法 如何创建C# Closure ? C# 批量生成随机密码,必须包含数字和字母,并用加密算法加密 C#中的foreach和yield 数组为什么可以使用linq查询 C#中的 具名参数 和 可选参数 显示实现接口 异步CTP(Async CTP)为什么那样工作? C#多线程基础,适合新手了解 C#加快Bitmap的访问速度 C#实现对图片文件的压

    以下为本次实践代码: using System; using System.Collections.Generic; using System.ComponentModel; using System ...

  2. spring boot / cloud (四) 自定义线程池以及异步处理@Async

    spring boot / cloud (四) 自定义线程池以及异步处理@Async 前言 什么是线程池? 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务.线 ...

  3. c#中@标志的作用 C#通过序列化实现深表复制 细说并发编程-TPL 大数据量下DataTable To List效率对比 【转载】C#工具类:实现文件操作File的工具类 异步多线程 Async .net 多线程 Thread ThreadPool Task .Net 反射学习

    c#中@标志的作用   参考微软官方文档-特殊字符@,地址 https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/toke ...

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

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

  5. 抓住异步编程async/await语法糖的牛鼻子: SynchronizationContext

    长话短说,本文带大家抓住异步编程async/await语法糖的牛鼻子: SynchronizationContext 引言 C#异步编程语法糖async/await,使开发者很容易就能编写异步代码. ...

  6. 温故知新,CSharp遇见异步编程(Async/Await),聊聊异步编程最佳做法

    什么是异步编程(Async/Await) Async/Await本质上是通过编译器实现的语法糖,它让我们能够轻松的写出简洁.易懂.易维护的异步代码. Async/Await是C# 5引入的关键字,用以 ...

  7. 异步编程Async/await关键字

    异步编程Async \await 关键字在各编程语言中的发展(出现)纪实. 时间 语言版本 2012.08.15 C#5.0(VS2012) 2015.09.13 Python 3.5 2016.03 ...

  8. C++笔记-并发编程 异步任务(async)

    转自 https://www.cnblogs.com/diysoul/p/5937075.html 参考:https://zh.cppreference.com/w/cpp/thread/lock_g ...

  9. MVC+Spring.NET+NHibernate .NET SSH框架整合 C# 委托异步 和 async /await 两种实现的异步 如何消除点击按钮时周围出现的白线? Linq中 AsQueryable(), AsEnumerable()和ToList()的区别和用法

    MVC+Spring.NET+NHibernate .NET SSH框架整合   在JAVA中,SSH框架可谓是无人不晓,就和.NET中的MVC框架一样普及.作为一个初学者,可以感受到.NET出了MV ...

随机推荐

  1. 如何系统地自学一门Python 语言(转)

    转自:http://www.phpxs.com/post/4521 零基础情况下,学一门语言充实下自己,Python,简洁.优美.容易使用,是一个很好的选择.那么如何系统地自学Python呢? 有的人 ...

  2. 配置tomcat解压版

    配置Tomcat[解压版] 选择解压版的Tomcat的理由是可以让我们使用多个Tomcat,但是配置上就会出现一些问题,需要我们手动进行更改配置.我的Tomcat版本是:apache-tomcat-6 ...

  3. CSS布局技巧 -- sticky属性

    在一些很长的表格中,往往需要使用表头悬浮的设计以方便用户使用,例如H5电商页面通过下滑展示大量商品列表时,顶部的导航栏需要在离开屏幕时,需要固定在屏幕顶部以方便用户筛选类别.这种效果一直以来需要通过J ...

  4. padding与margin的区别

    padding    是控件的内容相对控件的边缘的边距. margin      是控件边缘相对父空间的边距. android:gravity 属性是对该view 内容的限定.比如一个button 上 ...

  5. JS-sort排序

    var arr = [ 'c', 'd', 'a', 'e' ];// arr.sort();// alert( arr );var arr2 = [ 4,3,5,5,76,2,0,8 ];// ar ...

  6. 时空地图TimeGIS 可编辑ArcGIS的Shape矢量文件的地理信息系统

    时空地图 TimeGIS 6.0 是一个地理信息系统软件,它可以显示网络地图,编辑ArcGIS的SHP矢量文件格式,显示NETCDF等栅格文件,管理图层等. 在它的基础上,可以二次开发各种GIS应用, ...

  7. HTML的ul和li标签的使用

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  8. CentOS添加用户及赋予sudo权限

    在CentOS下添加一个用户假设用户名:username 密码:userpwd 新建用户: adduser username 修改密码: passwd username 根据提示重复输入两遍userp ...

  9. 成都印迹婚纱摄影 | yinjilove.com

    成都印迹婚纱摄影工作室 官方网站:http://yinjilove.com/ 联系方式:028-84278563 手机及微信号:18180642817 微信公众号:印迹摄影 地址:成都市锦江区牛王庙东 ...

  10. Web测试基础点

    摘自:软件工程师成长之路 1.获取当前使用的Flash播放器版本(Flash Player Version)信息 在浏览器地址栏输入http://www.playerversion.com/,即可显示