C#如何使用异步编程【BeginInvoke/EndInvoke】
怎么使用异步,就是用委托进行处理,如果委托对象在调用列表中只有一个方法,它就可以异步执行这个方法。委托类有两个方法,叫做BeginInvoke和EndInvoke,它们是用来异步执行使用。
异步有三种模式
- 等待模式,在发起了异步方法以及做了一些其它处理之后,原始线程就中断,并且等待异步方法完成之后再继续。
- 轮询模式,原始线程定期检查发起的线程是否完成,如果没有则可以继续做一些其它的事情。
- 回调模式,原始线程一直在执行,无需等待或检查发起的线程是否完成。在发起的线程中的引用方法完成之后,发起的线程就会调用回调方法,由回调方法在调用EndInvoke之前处理异步方法的结构。
在学习异步编程之前,先看看BeginInvoke和EndInvoke方法。
BeginInvoke方法
- 在调用BeginInvoke时,参数列表中的实参组成如下:
1) 引用方法需要的参数。
2) 两个额外的参数——callback参数和state参数。
- BeginInvoke从线程池中获取一个线程并且在新的线程开始时运行引用方法。
- BeginInvoke返回给调用线程一个实现IasyncResult接口的对象。这个接口引用包含了异步方法的当前状态,原始线程然后可以继续执行。
EndInvoke方法
- 它接受一个由BeginInvoke方法返回的IasyncResult对象的引用,并找到它关联的线程。
- 如果线程池的线程已经退出,EndInvoke做如下的事情。
1) 它清理退出线程的状态并且释放它的资源。
2) 它找到引用方法返回的值并且把它的值作为返回值。
- 如果当EndInvoke被调用时线程池的线程仍然在运行,调用线程就会停止并等待,直到清理完毕并返回值。因为EndInvoke是为开启的线程进行清理,所以必须确保对每一个BeginInvoke都调用EndInvoke。
- 如果异步方法触发了异常,在调用EndInvoke时会抛出异常。
等待模式
在这种模式里,原始线程发起一个异步方法的调用,做一些其它处理,然后停止并等待,直到开启的线程结束。如下图




这段代码产生了如下输出。

既然我们已经看到了BeginInvoke和EndInoke的最简单形式,可以进一步了解IasyncResult了,它是使用这些方法的必要部分。
BeginInvoke返回一个IasyncResult接口的引用(内部是AsyncResult类的对象)。AsyncResult类表现了异步方法的状态。如下图:

- 当我们调用委托对象的BeginInvoke方法时,系统创建了一个AsyncResult类的对象。然而,它不返回类的对象的引用,而是返回对象中包含的IasyncResult接口的引用。
- AsyncResult对象包含一个叫做AsyncDelegate的属性,它返回一个指向被调用来开启异步方法的委托的引用。但是这个属性是类对象的一部分而是接口的一部分。
- IsCompleted属性返回一个布尔值,表示异步方法是否完成。
- AsyncState属性返回一个对象的引用,它被作为BeginInvoke方法调用时的state参数。它返回object类型的引用,稍后再讲解。。
轮询模式
在轮询模式中,原始线程发起了异步方法的调用,做一些其它处理,然后使用IAsyncResult对象的IsCompleted属性来定期检查开启的线程是否完成。如果异步方法已经完成,原始线程就调用EndInvoke并继续。否则,它做一些其它处理,然后过一会儿再检查。如下图:

这段代码产生了如下输出。

回调模式
在之前的等待模式与轮询模式中,初始线程继续它自己的控制流程,直到它知道开启的线程完成。然后,它获取结果并继续。
回调模式的不同之处在于,一旦初始线程发起了异步方法,它就自己管自己了,不再考虑同步。当异步方法调用结束之后,系统调用一个用户自定义的方法来处理结束,并且调用委托的EndInvoke方法。这个用户自定义的方法叫做回调方法或回调。
BeginInvoke的参数列表中最后的两个额外参数被回调方法用做:
1) 第一个参数,callback参数,是回调方法的名字。
2) 第二个参数,state参数,可以是null或要传入回调方法的一个对象数据。我们可以通过使用IAsyncResult参数的AsyncState属性来获取这个对象。参数类型是object
- 回调方法的签名和返回类型必须和AsyncCallback委托类型所描述的形式一致。它需要方法接受一个IAsyncResult作为参数并且返回类型是void。如下所示:
Void AsyncCallback(IAsyncResult iar)
- 在回调方法内,我们的代码应该调用委托的EndInvoke方法来处理异步方法执行后的输出值。要调用委托的EndInvoke方法,我们肯定需要委托对象的引用,而它在初始线程中,不在开启线程中。如果我们不使用BeginInvoke的state参数作其它的用途,可以使用它发送委托的引用给回调方法。否则,我们可以从发送给方法作为参数的IAsyncResult对象中提取出委托的引用。
1) 给回调方法的参数只有一个,就是刚结束的异步方法的IAsyncResult接口的引用,要记住,IAsyncResult接口对象在AsyncResult类对象的内部。
2) 尽管IAsyncResult接口没有委托对象的引用,而包含它的AsyncResult类对象却有委托对象的引用。
3) 有了类对象的引用,我们现在就可以调用类对象的AsyncDelegate属性并且把它转化为合适的委托类型。这样就得到了委托引用,我们可以用它来调用EndInvoke。
如下代码所示:




这段代码产生了如下输出。

那么以上的异步内容已经基本讲解完毕。
说明:异步编程在.Net4.0中,有了更好的方式处理,简化了编程的复杂度,使用Task类(在System.Threading.Tasks命名空间中)处理,但原理是一样的。
原文地址:http://www.cnblogs.com/zwt-blog/p/4812530.html#3611906
C#如何使用异步编程【BeginInvoke/EndInvoke】的更多相关文章
- [C#学习笔记之异步编程模式2]BeginInvoke和EndInvoke方法 (转载)
为什么要进行异步回调?众所周知,普通方法运行,是单线程的,如果中途有大型操作(如:读取大文件,大批量操作数据库,网络传输等),都会导致方法阻塞,表现在界面上就是,程序卡或者死掉,界面元素不动了,不响应 ...
- 多线程 异步 beginInvoke EndInvoke 使用
有许多耗时操作时,还要响应用户操作.这时候就需要用其他线程或者异步来搞.本来是改造公司的日志组件.因为多上了个国外大区的业务到来本系统来.这个系统其他地方都好就是日志,动不动就要死给我们看.有时候寻找 ...
- 异步编程 In .NET
概述 在之前写的一篇关于async和await的前世今生的文章之后,大家似乎在async和await提高网站处理能力方面还有一些疑问,博客园本身也做了不少的尝试.今天我们再来回答一下这个问题,同时我们 ...
- C#异步编程(二)
async和await结构 序 前篇博客异步编程系列(一) 已经介绍了何谓异步编程,这篇主要介绍怎么实现异步编程,主要通过C#5.0引入的async/await来实现. BeginInvoke和End ...
- C# - 多线程 之 异步编程
异步编程 同步编程,请求响应模型,同步化.顺序化.事务化. 异步编程,事件驱动模型,以 Fire and Forget 方式实现. 异步编程模式 -§- 异步编程模型 (APM) 模式: IAsyn ...
- 多线程之异步编程: 经典和最新的异步编程模型,async与await
经典的异步编程模型(IAsyncResult) 最新的异步编程模型(async 和 await) 将 IAsyncInfo 转换成 Task 将 Task 转换成 IAsyncInfo 示例1.使用经 ...
- 多线程之异步编程: 经典和最新的异步编程模型, IAsyncInfo 与 Task 相互转换
经典的异步编程模型(IAsyncResult) 最新的异步编程模型(async 和 await) 将 IAsyncInfo 转换成 Task 将 Task 转换成 IAsyncInfo 示例1.使用经 ...
- 《learning hard C#学习笔记》读书笔记(20)异步编程
20.1 什么是异步编程异步编程就是把耗时的操作放进一个单独的线程中进行处理. 20.2 同步方式存在的问题 namespace 异步编程 { public partial class For ...
- 【转】【C#】C# 5.0 新特性——Async和Await使异步编程更简单
一.引言 在之前的C#基础知识系列文章中只介绍了从C#1.0到C#4.0中主要的特性,然而.NET 4.5 的推出,对于C#又有了新特性的增加--就是C#5.0中async和await两个关键字,这两 ...
随机推荐
- NGINX编译选项
一.减小编译后的文件大小Nginx源码文件解压后,找到auto/cc/gcc文件,注释或删除:# debugCFLAGS= "CFLAGS -g"即可取消debug模式.二:为特定 ...
- 性能测试工具Jmeter01-简介
Jmeter介绍: Apache JMeter是Apache组织的开放源代码项目,是一个纯Java桌面应用,用于压力测试和性能测试.最初被设计用于Web应用测试后来扩展到其它测试领域 Jmeter有啥 ...
- ORACLE SQL 实现IRR的计算
一.IRR计算的原理: 内部收益率(Internal Rate of Return (IRR)),就是资金流入现值总额与资金流出现值总额相等.净现值等于零时的折现率. 用公式 标识:-200+[30/ ...
- window对象的事件:onresize、onpageshow、onload
onresize事件非常容易理解: 即当窗口或者框架的大小发生变化时,就会触发此事件. 实例demo onpageshow事件是当用户浏览网页时触发的. onpageshow 事件类似于 onload ...
- AndroidStudio3.0的安装和配置笔记
开发Android项目要搭建开发环境.可以选择使用Eclipse安装ADT插件来开发安卓项目,也可以使用谷歌的官方IDE——AndroidStudio3.0. AndroidStudio3.0安装的具 ...
- 初学者配置第一个spring mvc Demo
1.web.xml的配置 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi= ...
- ThinkPHP报Class 'Core\Log' not found竟然是由这个原因导致的
项目在开发阶段运行的好好的(Debug=true),上线后(Debug=false)其中有一个页面报“对不起,您的页面暂进无法找到!”错误.摸不清头脑,看看了这个页面也没有什么两样,可就是提示这句话, ...
- spring各版本之间的特性增加
一.Spring3.0以后不再提供一个大的完整的jar包,而是分成20个小的jar包: org.springframework.aop, 包含在应用中使用Spring的AOP特性时所需的类. org. ...
- SSL、数字签名、CA 工作原理
SSL.数字签名.CA 工作原理 对称加密和非对称加密介绍和区别 什么是对称加密技术? 对称加密采用了对称密码编码技术,它的特点是文件加密和解密使用相同的密钥,即加密密钥也可以用作解密密钥,这种方 ...
- poj 1155 输入输出问题
http://acm.hust.edu.cn/vjudge/problem/16417 重做了一遍poj 1155 题目大意:给定一棵树,1为根结点表示电视台,有m个叶子节点表示客户,有n-m-1个中 ...