Asycn/Await 异步编程初窥
经过两天密集型的学习,翻阅了大量 webpages ,点击了不少重点 blogs,总算基本了解了一些 async/await 搭配使用的入门技巧,总结一下
1. async/await 应该只是语法上的甜点,让想使用异步方法运行程序的程序员能够专心专注代码逻辑,而别被原来的 Begin... End... 型或是IAsync ...Async 的老式异步带的越来越远。想起刚试着编写 Tcp Listener的时候,真是噩梦。异步响应必须放在另一个回调方法或是事件中,而从异步响应产生的异步接收又必须再次放到另一个回调方法或是事件中,更可怕的是,如何循环它们。
2. async/await 标识的方法,“本身不主动创建额外线程”——这句话很容易让人误解。《Async 和 Await 异步编程的原理》这篇文章写的比较详细,异步,必然多线程,更何况是从 UI 线程启动的。只是这种多线程被Framework透明掉了,使用者不必自己在这方面去走脑子怎么创建线程,怎么回收,怎么捕捉异常,还得让代码好看一点。
3. await 让我开始的时候陷入了一个误区,认为使用 var result = await FunRun(...) 这种写法,FunRun()方法就会异步运行而不会阻塞UI线程,这是错的,我忽略了一个很严重的问题。先看一下原来错误的代码:
private async Task<TimeSpan> Download(Uri address, string fileName)
{
this.uri = address;
this.fileName = fileName;
DateTime start = DateTime.Now;
//
HttpWebRequest request;
HttpWebResponse response = null;
try
{
request = (HttpWebRequest)WebRequest.Create(address);
response = (HttpWebResponse)request.GetResponse();
using (Stream httpStream = response.GetResponseStream())
{
using (FileStream writer = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read))
{
byte[] buffer = new byte[];
int readLength = httpStream.Read(buffer, , buffer.Length);
//
while (readLength > )
{
writer.Write(buffer, , readLength);
readLength = httpStream.Read(buffer, , buffer.Length);
}
}
}
}
catch(Exception)
{
if (response != null) { response.Close(); }
} return DateTime.Now - start;
}
代码完成下载一个资源到指定位置的功能,本身逻辑没有错误,看起来这似乎是一个标准的带有 async 标记和 Task<T> 返回类型的方法,所以我信心慢慢的调用了它。
private async void button1_Click(object sender, EventArgs e)
{
//略过部分逻辑判断的东西
...... TestApp.HttpDownloader.HttpDownloaderEngine hdEngine = new HttpDownloaderEngine();
var time = await hdEngine.Download(address, saveFileTextBox.Text);
MessageBox.Show(string.Format("下载完成,共耗时 {0} 秒", time.Seconds.ToString()));
}
调用错误写法的方法
Button1 的 Click 事件本身也没有问题,我还细心的加上了 async 标记(当然,不加也不让我过去啊),一切很好我即刻运行,结果让我很困惑,的确成功的下载了 Mp3 到我的电脑,可不管时间长短,我的 UI 依旧像同步的一样,不能响应知道执行完成。问题处在哪里?
人是需要休息的,学习->休息->消化,经过再次梳理和查看资料,我找出了第 3 点开头我说的,Bug 在于 HttpDownloadEngine 的 Download 方法我虽然标记了 async,button_click 误以为 Download 方法可以完成异步工作,button_click 是没错的,错在 Download 方法内不,没有任何“异步执行的代码”!也就是说,Download 方法内没有出现一个 await ,这使得标记了 async 的 Download 方法依旧是同步的,button_click 调用了一个同步方法在同步执行。
如何修改呢,在 Download 方法内的关键处执行 await Task<T> ....Async ,如 readLength = await responseStream.ReadAsync(buffer, 0, buffer.Length);,关键处是指的确需要异步执行的地方。
4. 我要感谢 Microsoft,我不是大神,我是个爱好者,是微软借鉴并创造了 .Net 和无与伦比的 VS,让我和像我一样的人都能领略计算机的更多魅力,这种魅力,来自于创造和分享给他人。
贴上一个下载的结果图

Asycn/Await 异步编程初窥的更多相关文章
- Asycn/Await 异步编程初窥(二)
经过总过4天的学习和实践,做完了 WinForm 下 .Net 4.5 的基本异步应用,实现了一个 Http 协议下载的测试程序,为以后使用 .Net 4.5 积累知识和经验.这个小程序完成这样几个作 ...
- Asycn/Await 异步编程
Asycn/Await 异步编程初窥(二) 经过总过4天的学习和实践,做完了 WinForm 下 .Net 4.5 的基本异步应用,实现了一个 Http 协议下载的测试程序,为以后使用 .Net ...
- Async和Await异步编程的原理
1. 简介 从4.0版本开始.NET引入并行编程库,用户能够通过这个库快捷的开发并行计算和并行任务处理的程序.在4.5版本中.NET又引入了Async和Await两个新的关键字,在语言层面对并行编程给 ...
- async And await异步编程活用基础
原文:async And await异步编程活用基础 好久没写博客了,时隔5个月,奉上一篇精心准备的文章,希望大家能有所收获,对async 和 await 的理解有更深一层的理解. async 和 a ...
- 【转】C# Async/Await 异步编程中的最佳做法
Async/Await 异步编程中的最佳做法 Stephen Cleary 近日来,涌现了许多关于 Microsoft .NET Framework 4.5 中新增了对 async 和 await 支 ...
- 李洪强iOS开发之函数式 编程初窥
函数式 编程初窥 最近在学习Erlang和Python.Erlang是完全的函数式编程语言,Python语言是面向对象的语言,但是它的语法引入了大量的函数式编程思想.越研究越觉得函数式的编程思路可 ...
- .NET Web应用中为什么要使用async/await异步编程
前言 什么是async/await? await和async是.NET Framework4.5框架.C#5.0语法里面出现的技术,目的是用于简化异步编程模型. async和await的关系? asy ...
- C#中 Thread,Task,Async/Await 异步编程
什么是异步 同步和异步主要用于修饰方法.当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法:当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务,调 ...
- async/await 异步编程(转载)
转载地址:http://www.cnblogs.com/teroy/p/4015461.html 前言 最近在学习Web Api框架的时候接触到了async/await,这个特性是.NET 4.5引入 ...
随机推荐
- Linux_修改创建文件夹时默认权限(修改为能上传)
1:查看当前权限 umask 0022 意思就是权限为:777-022 =755 读 2:临时修改 umask 020 020 意思为:777-020=757 读写上传 3:永久修改 回到根目录 cd ...
- 归并排序 & 快速排序
归并排序 归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用. 将已有序的子序列合并,得到完全有序的序列:即先使每个子序列有 ...
- TempData,ViewData和ViewBag的比较
TempData,ViewData和ViewBag的比较 学习ASP.NET有大约一个月了,一直都是半生不熟的,因为之前的很长时间都是在做java开发,没有时间静下来心来学习,加上ASP.NET的框架 ...
- HTML的标签canvas
定义和使用方法 <canvas> 标签定义图形,比方图表和其它图像. <canvas> 标签仅仅是图形容器,您必须使用脚本来绘制图形. 实例 怎样通过 canvas 元素来显示 ...
- IIS 7.5 使用URL Rewrite模块简单设置网页跳转
原文 IIS 7.5 使用URL Rewrite模块简单设置网页跳转 我们都知道Apache可以在配置文件里方便的设置针对网页或网站的rewrite,但是最近接手了一组IIS服务器,发现这货简单的没有 ...
- Java判断当前用户数及当前登录用户数工具类-session原理
JavaWeb开发中,有时会遇到统计或管理用户登录数或者当前在线多少用户,分别都是谁的情况.当然,实现途径多种多样.下面列举一下通过session实现的一种统计. public class MySes ...
- [连载]Java程序设计(04)---任务驱动的方法:工资结算系统
任务:或在公司,该公司将其分为三类人员:部门经理.销售员.在发工资的时候,部门经理拿固定月薪8000元.技术人员按每小时100元领取月薪.销售人员依照500元底薪加当月销售额的4%进行提成.设计并实现 ...
- mongodb操作之使用javaScript实现多表关联查询
一.数据控制 mongodb操作数据量控制,千万控制好,不要因为操作的数据量过多而导致失败. 演示一下发生此类错误的错误提示:
- 基于科大讯飞语音云windows平台开发
前记: 前段时间公司没事干,突发奇想想做一个语音识别系统,看起来应该非常easy的,但做起来却是各种问题,这个对电气毕业的我,却是挺为难的.谷姐已经离我们而去,感谢度娘,感谢CSDN各位大神,好歹也做 ...
- QT最简单的程序执行过程分析(内含C++基础知识)
打开QT Creator,新建一个“应用程序-Qt Widgets Application”项目: 输入名称scdc之后点击下一步. 在“构建套件”这个页面中直接点出下一步,然后再输入自己的类名Dat ...