1:C#的三种异步的详细介绍及实现
一、介绍异步的前世今生:
- 异步编程模型 (APM,Asynchronous Programming Model) 模式(也称 IAsyncResult 模式),在此模式中异步操作需要 Begin 和 End 方法(比如用于异步写入操作的 BeginWrite 和 EndWrite)。 对于新的开发工作不再建议采用此模式
- 基于事件的异步模式 (EAP,Event-based Asynchronous Pattern),这种模式需要 Async 后缀,也需要一个或多个事件、事件处理程序委托类型和 EventArg 派生类型。 EAP 是在 .NET Framework 2.0 中引入的。 对于新的开发工作不再建议采用此模式。
- 基于任务的异步模式 (TAP, Task-based Asynchronous Pattern) 使用一种方法来表示异步操作的启动和完成。 TAP 是在 .NET Framework 4 中引入的,并且它是在 .NET Framework 中进行异步编程的推荐使用方法。 C# 中的 async 和 await 关键词以及 Visual Basic 语言中的 Async 和 Await 运算符为 TAP 添加了语言支持。
二、我这里以一个Read方法为例,将异步操作简单进行讲解:
public class MyClass
{
public int Read(byte [] buffer, int offset, int count);
}
public class MyClass
{
public IAsyncResult BeginRead(
byte [] buffer, int offset, int count,
AsyncCallback callback, object state);
public int EndRead(IAsyncResult asyncResult);
}
优点是简单,缺点是当实现复杂的业务的时候很麻烦,比如下载 A 成功后再下载 b,如果下载 b 成功再下载 c,否则就下载 d。
EAP 的类的特点是:一个异步方法配一个***Completed 事件。.Net 中基于 EAP 的类比较少。也有更 好的替代品,因此了解即可。
public class MyClass
{
public void ReadAsync(byte [] buffer, int offset, int count);
public event ReadCompletedEventHandler ReadCompleted;
}
public class MyClass
{
public Task<int> ReadAsync(byte [] buffer, int offset, int count);
}
三、我这里以一个下载资料方法为例,将异步操作简单进行讲解:
1.普通同步操作
private void btn_Click(object sender, EventArgs e)//这是同步按钮
{
using (WebClient wc = new WebClient())
{
// 我们尝试去下载 python 的安装包。
wc.DownloadFile("https://file.aaoit.com/upload/AllLearnFile/admin//2018/4/24/c558f2dc9d6310bfe3cd1788094d3f0c.pdf", "C#课程第一单元学习.pdf");
}
label1.ForeColor = Color.Blue;
label1.Text = "下载完成。";//提示的label
}
2.基于事件的异步模式(EAP)
private void btnEAP_Click(object sender, EventArgs e)//这是EAP按钮
{
using (WebClient wc = new WebClient())
{
// 我们尝试去下载 python 的安装包。
// 下载完成时会有事件通知。
wc.DownloadFileCompleted += Wc_DownloadFileCompleted;
wc.DownloadFileAsync(new Uri("https://file.aaoit.com/upload/AllLearnFile/admin//2018/4/24/c558f2dc9d6310bfe3cd1788094d3f0c.pdf"), "C#课程第一单元学习EAP.pdf");
}
} private void Wc_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
label1.ForeColor = Color.Yellow;
label1.Text = "下载完成。";//提示的label
}
3.异步编程模型(APM)
private void btnAPM_Click(object sender, EventArgs e)//这是APM按钮
{
FileStream fs = File.OpenRead("e:/cc.txt");
byte[] buffer = new byte[];
IAsyncResult aResult = fs.BeginRead(buffer, , buffer.Length, null, null);
aResult.AsyncWaitHandle.WaitOne();//等待任务执行结束
MessageBox.Show(Encoding.UTF8.GetString(buffer));
fs.EndRead(aResult);
}
4.基于任务的异步模式(TAP)
private async void btnTAP_Click(object sender, EventArgs e)//这是TAP按钮
{
using (WebClient wc = new WebClient())
{
// 我们尝试去下载 python 的安装包。
Task task = wc.DownloadFileTaskAsync("https://file.aaoit.com/upload/AllLearnFile/admin//2018/4/24/c558f2dc9d6310bfe3cd1788094d3f0c.pdf", "C#课程第一单元学习TAP.pdf");
// 可以在这里执行代码。
await task;
}
label1.ForeColor = Color.Red;
label1.Text = "下载完成。";//提示的label
}
四、TPL(Task Parallel Library)是.Net 4.0 之后带来的新特性,更简洁,更方便。现在在.Net 平台下已经大面积使用。
TPL即任务并行库,是.NET Framework 4版本中的新鲜物,是System.Threading 和 System.Threading.Tasks 命名空间中的一组公共类型和 API。TPL 的目的在于简化向应用程序中添加并行性和并发性的过程,从而提高开发人员的工作效率。 TPL 会动态地按比例调节并发程度,以便最有效地使用所有可用的处理器。此外,TPL 还处理工作分区、ThreadPool 上的线程调度、取消支持、状态管理以及其他低级别的细节操作。通过使用 TPL,您可以在将精力集中于程序要完成的工作,同时最大程度地提高代码的性能。
1.实现读取txt
private async void btnTPL_Click(object sender, EventArgs e)//这是TPL按钮
{
FileStream fs = File.OpenRead("e:/cc.txt");
byte[] buffer = new byte[];
int len = await fs.ReadAsync(buffer, , buffer.Length);
MessageBox.Show("读取了" + len + "个字节");
MessageBox.Show(Encoding.UTF8.GetString(buffer));
}
注意方法中如果有 await,则方法必须标记为 async,不是所有方法都可以被轻松的标记 为 async。WinForm 中的事件处理方法都可以标记为 async、MVC 中的 Action 方法也可以标 记为 async、控制台的 Main 方法不能标记为 async。 TPL 的特点是:方法都以 XXXAsync 结尾,返回值类型是泛型的 Task<T>。 TPL 让我们可以用线性的方式去编写异步程序,不再需要像 EAP 中那样搞一堆回调、逻 辑跳来跳去了。await 现在已经被 JavaScript 借鉴走了! 用 await 实现“先下载 A,如果下载的内容长度大于 100 则下载 B,否则下载 C”就很容易了 。
2. WebClient 的 TPL 用法:
private async void btnTPLWebClientNo_Click(object sender, EventArgs e)//这是TPLUI不卡死按钮
{
WebClient wc = new WebClient();
string html = await wc.DownloadStringTaskAsync("https://www.aaoit.com");//不要丢了 await
MessageBox.Show(html);
} private void btnTPLWebClientYES_Click(object sender, EventArgs e)//这是TPLUI卡死按钮
{
WebClient wc = new WebClient();
var task = wc.DownloadStringTaskAsync("https://www.aaoit.com");
task.Wait();
MessageBox.Show(task.Result);
}
WebClient、Stream、Socket 等这些“历史悠久”的类都同时提供了 APM、TPL 风格的 API,甚至有的还提供了 EAP 风格的 API。尽可能使用 TPL 风格的。
1:C#的三种异步的详细介绍及实现的更多相关文章
- C# 写入XML文档三种方法详细介绍
		三个类将同样的xml内容写入文档,介绍了如何使用XmlDocument类对XML进行操作,以及如何使用LINQ to XML对XML进行操作. 它们分别使用了XmlDocument类和XDocum ... 
- Mysql Binlog三种格式详细介绍
		一.MySQL Binlog格式介绍 mysql binlog日志有三种格式,分别为Statement,MiXED,以及ROW! 查看binlog的格式的脚本: 二.binlog 的不同模式有什么区别 ... 
- [转]Apache HTTP Server 与 Tomcat 的三种连接方式介绍
		首先我们先介绍一下为什么要让 Apache 与 Tomcat 之间进行连接.事实上 Tomcat 本身已经提供了 HTTP 服务,该服务默认的端口是 8080,装好 tomcat 后通过 8080 端 ... 
- STM32三种BOOT模式介绍
		一.三种BOOT模式介绍 所谓启动,一般来说就是指我们下好程序后,重启芯片时,SYSCLK的第4个上升沿,BOOT引脚的值将被锁存.用户可以通过设置BOOT1和BOOT0引脚的状态,来选择在复位后的启 ... 
- 【Hadoop离线基础总结】Apache Hadoop的三种运行环境介绍及standAlone环境搭建
		Apache Hadoop的三种运行环境介绍及standAlone环境搭建 三种运行环境 standAlone环境 单机版的hadoop运行环境 伪分布式环境 主节点都在一台机器上,从节点分开到其他机 ... 
- Apache HTTP Server 与 Tomcat 的三种连接方式介绍(转)
		首先我们先介绍一下为什么要让 Apache 与 Tomcat 之间进行连接.事实上 Tomcat 本身已经提供了 HTTP 服务,该服务默认的端口是 8080,装好 tomcat 后通过 8080 端 ... 
- c++中new的三种用法详细解析
		转载至: http://www.jb51.net/article/41524.htm 以下的是对c++中new的三种使用方法进行了详细的分析介绍,需要的朋友可以过来参考下,希望对大家有所帮助. 一. ... 
- Apache HTTP Server 与 Tomcat 的三种连接方式介绍
		本文转载自IBM developer 首先我们先介绍一下为什么要让 Apache 与 Tomcat 之间进行连接.事实上 Tomcat 本身已经提供了 HTTP 服务,该服务默认的端口是 8080,装 ... 
- 转自IBM:Apache HTTP Server 与 Tomcat 的三种连接方式介绍
		http://www.ibm.com/developerworks/cn/opensource/os-lo-apache-tomcat/index.html 整合 Apache Http Server ... 
随机推荐
- 获取properties配置
			1. 使用@Value @Value("${swagger.enable}") 使用Spring的PropertyPlaceholderConfigurer关联 @Val ... 
- README.md的编写
			1.编辑README文件 大标题(一级标题):在文本下面加等于号,那么上方的文字就变成了大标题,等于号的个数无限制,但一定要大于0 大标题 ==== 中标题(二级标题):在文本下面加下划线,那么上方的 ... 
- XX公司的CA,与平台融合解决方法。。。。。
			1,jsp 的编写要求 <script language="javascript" type="text/javascript"> var clie ... 
- Solr集群—SolrCloud
			1. 学习计划 1.solr集群搭建 2.使用solrj管理solr集群 3.把搜索功能切换到集群版 2. 什么是SolrCloud SolrCloud(solr 云)是Solr提供的分布式搜 ... 
- hdu1710-Binary Tree Traversals                       (由二叉树的先序序列和中序序列求后序序列)
			http://acm.hdu.edu.cn/showproblem.php?pid=1710 Binary Tree Traversals Time Limit: 1000/1000 MS (Java ... 
- 欢迎加入本人建的QQ群,讨论技术,生活及每天都有招聘信息
			银狐AS3游戏2 3438131 银狐AS3Help 1803321 银狐U3D 167024653 银狐AS3转H5 467565102 本人在MSDN上的帐号 https://social.msd ... 
- 7-set用法详解
			C++中set用法详解 转载 http://blog.csdn.net/yas12345678/article/details/52601454 C++ / set 更详细见:http://www.c ... 
- Oracle表格字段采用sequence进行自增长时,采用Dbutils进行insert或update数据时的处理技巧
			// 定义插入记录的方法 public Teacher insert(String name, String gender, Double score) { // 获得连接 Connection co ... 
- Checked异常和Runtime异常体系
			Java的异常被分为两大类:Checked异常和Runtime异常(运行时异常).所有的RuntimeException类及其子类的实例被称为Runtime异常:不是RuntimeException类 ... 
- Boost线程详解
			一.创建一个线程 创建线程 boost::thread myThread(threadFun); 需要注意的是:参数可以是函数对象或者函数指针.并且这个函数无参数,并返回void类型. 当一个thre ... 
