收藏地址  http://aierong.cnblogs.com/archive/2005/05/25/162308.html

让我们来看看同步异步的区别:
同步方法调用在程序继续执行之前需要等待同步方法执行完毕返回结果
异步方法则在被调用之后立即返回以便程序在被调用方法完成其任务的同时执行其它操作

.NET框架基类库中有好几种类都可以提供同步和异步的方法调用。
因为同步方法调用会导致程序流程中途等待,所以采用同步方法的情况下往往会导致程序执行的延迟
相比来说,在某些条件下选择异步方法调用就可能更好一些
例如,有的时候程序需要给多个Web服务发出请求,还有远程处理信道(HTTP、TCP)和代理,这时就最好采用异步方法

.NET Framework允许异步调用任何方法,定义与需要调用的方法具有相同签名的委托
CLR将自动为该委托定义添加适当签名的BeginInvoke虚方法和EndInvoke虚方法和Invoke方法。

关于委托的这3个方法的详细说明可以参考这文章
http://www.cnblogs.com/aierong/archive/2005/05/25/162181.html

我们先来了解这2个方法和一个委托和一个接口:
(1)
BeginInvoke方法用于启动异步调用
它与您需要异步执行的方法具有相同的参数,只不过还有两个额外的参数,将 AsyncCallback 和 AsyncState(可通过 IAsyncResult 接口的

AsyncState 属性获得)作为最后两个参数,如没有可以为空.
BeginInvoke立即返回,不等待异步调用完成。
BeginInvoke返回IasyncResult,可用于监视调用进度。

结果对象IAsyncResult是从开始操作返回的,并且可用于获取有关异步开始操作是否已完成的状态。
结果对象被传递到结束操作,该操作返回调用的最终返回值。
在开始操作中可以提供可选的回调。如果提供回调,在调用结束后,将调用该回调;并且回调中的代码可以调用结束操作。

(2)
EndInvoke方法用于检索异步调用结果。
在调用BeginInvoke后可随时调用EndInvoke方法,注意:始终在异步调用完成后调用EndInvoke.
如果异步调用未完成,EndInvoke将一直阻塞到异步调用完成。
EndInvoke的参数包括需要异步执行的方法的out和ref参数以及由BeginInvoke返回的IAsyncResult。
要注意的是,始终在异步调用完成后调用EndInvoke

(3)
AsyncCallback委托用于指定在开始操作完成后应被调用的方法
AsyncCallback委托被作为开始操作上的第二个到最后一个参数传递
代码原型如下:
[Serializable]
public delegate void AsyncCallback(IAsyncResult ar);

(4)
IAsyncResult接口
它表示异步操作的状态.
该接口定义了4个公用属性

实际上,发起和完成.NET异步调用有4种方案可供你选择
1.方案1-自己调用EndInvoke方法
异步执行方法的最简单方式是以BeginInvoke开始,对主线程执行一些操作,然后调用EndInvoke,EndInvoke直到异步调用完成后才返回

还是先来段自己喜欢的控制台代码:

 1using System;
 2
 3namespace ConsoleApplication1
 4{
 5    class Class1
 6    {
 7        public delegate void AsyncEventHandler();
 8
 9        void Event1()
10        {
11            Console.WriteLine("Event1 Start");
12            System.Threading.Thread.Sleep(2000);
13            Console.WriteLine("Event1 End");
14        }
15
16        void Event2()
17        {
18            Console.WriteLine("Event2 Start");
19            int i=1;
20            while(i<1000)
21            {
22                i=i+1;
23                Console.WriteLine("Event2 "+i.ToString());
24            }
25            Console.WriteLine("Event2 End");
26        }
27
28        void CallbackMethod(IAsyncResult ar) 
29        {
30            ((AsyncEventHandler) ar.AsyncState).EndInvoke(ar);
31        }
32
33
34        [STAThread]
35        static void Main(string[] args)
36        {
37            long start=0;
38            long end=0;
39            Class1 c = new Class1();
40            Console.WriteLine("ready");
41            start=DateTime.Now.Ticks;
42
43            AsyncEventHandler asy = new AsyncEventHandler(c.Event1);
44            IAsyncResult ia=asy.BeginInvoke(null,null);
45            c.Event2();
46            asy.EndInvoke(ia);
47            
48            end =DateTime.Now.Ticks;
49            Console.WriteLine("时间刻度差="+ Convert.ToString(end-start) );
50            Console.ReadLine();
51        }
52    }
53}
54

此程序简单,异步的处理过程在代码43-46这几行
结果如下:

现在让我们来看看同步处理
修改代码43-46这几行代码:
c.Event1();
c.Event2();
结果如下:

前者的时间刻度大大小于后者
我们可以明显地看到异步运行的速度优越性

2.方案2-采用查询(IsCompleted属性)
IAsyncResult.IsCompleted属性获取异步操作是否已完成的指示,发现异步调用何时完成.
再次修改代码43-46这几行代码:
AsyncEventHandler asy = new AsyncEventHandler(c.Event1);
IAsyncResult ia=asy.BeginInvoke(null,null);
c.Event2();
while(!ia.IsCompleted)
{
}
asy.EndInvoke(ia);

3.方案3-采用AsyncWaitHandle来等待方法调用的完成
IAsyncResult.AsyncWaitHandle属性获取用于等待异步操作完成的WaitHandle
WaitHandle.WaitOne方法阻塞当前线程,直到当前的WaitHandle收到信号
使用WaitHandle,则在异步调用完成之后,但在通过调用EndInvoke结果之前,可以执行其他处理
再次修改代码43-46这几行代码:
AsyncEventHandler asy = new AsyncEventHandler(c.Event1);
IAsyncResult ia=asy.BeginInvoke(null,null);
c.Event2();
ia.AsyncWaitHandle.WaitOne();

4.方案4-利用回调函数
如果启动异步调用的线程不需要处理调用结果,则可以在调用完成时执行回调方法
要使用回调方法,必须将代表该方法的AsyncCallback委托传递给BeginInvoke
再次修改代码43-46这几行代码:
AsyncEventHandler asy = new AsyncEventHandler(c.Event1);
asy.BeginInvoke(new AsyncCallback(c.CallbackMethod),asy);
c.Event2();

希望上面提到的知识对你有所提示
当然欢迎交流和指正

转载于:https://www.cnblogs.com/runfeng/archive/2006/05/14/400127.html

Mcad学习笔记之异步编程(AsyncCallback委托,IAsyncResult接口,BeginInvoke方法,EndInvoke方法的使用小总结)...相关推荐

  1. Mcad学习笔记之异步编程(AsyncCallback委托,IAsyncResult接口,Begin

    http://www.chenjiliang.com/Article/View.aspx?ArticleID=2071 让我们来看看同步异步的区别:  同步方法调用在程序继续执行之前需要等待同步方法执 ...

  2. Mcad学习笔记之委托再理解(delegate的构造器,MulticastDelegate,BeginInvoke,EndInvoke,Invoke4个方法的探讨)...

    相关文章导航 Sql Server2005 Transact-SQL 新兵器学习总结之-总结 Flex,Fms3相关文章索引 FlexAir开源版-全球免费多人视频聊天室,免费网络远程多人视频会议系统 ...

  3. Mcad学习笔记之通过反射调用類的方法,屬性,字段,索引器(2種方法)

    相关文章导航 Sql Server2005 Transact-SQL 新兵器学习总结之-总结 Flex,Fms3相关文章索引 FlexAir开源版-全球免费多人视频聊天室,免费网络远程多人视频会议系统 ...

  4. Mcad学习笔记之Microsoft Windows服务

    相关文章导航 Sql Server2005 Transact-SQL 新兵器学习总结之-总结 Flex,Fms3相关文章索引 FlexAir开源版-全球免费多人视频聊天室,免费网络远程多人视频会议系统 ...

  5. C# 学习笔记——PL 并行编程 TPL 和传统 .NET 异步编程

    C# 学习笔记--PL 并行编程 TPL 和传统 .NET 异步编程 Task C# 多线程和异步模型 TPL模型 Task,异步,多线程简单总结 1,如何把一个异步封装为Task异步 Task.Fa ...

  6. Python学习笔记:异步IO(3)

    前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...

  7. Python学习笔记:异步IO(2)

    前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...

  8. Python学习笔记:异步IO(1)

    前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...

  9. java学习笔记15--多线程编程基础2

    本文地址:http://www.cnblogs.com/archimedes/p/java-study-note15.html,转载请注明源地址. 线程的生命周期 1.线程的生命周期 线程从产生到消亡 ...

最新文章

  1. 又一例“监视员工?”百度回应:和 996 无关,目前没有任何应用
  2. CJIS安全政策:企业如何确保FIPS合规性?
  3. 《Java 核心技术卷1 第10版》学习笔记------日志
  4. 误差error,偏置bias,方差variance的见解
  5. java的xml面试题_Java程序员的10个XML面试问答
  6. 杨辉三角_二维数组的好例子(转载)
  7. 4、http编程——setsockopt函数
  8. zabbix2.4监控mysql_Zabbix 2.4.5自带MySQL监控的配置使用教程
  9. JavaScript专题之跟着 underscore 学节流
  10. POJ 1182 食物链
  11. 方法论 | 多因子策略的五大讨论(思维导图收藏版)
  12. 多智能体强化学习之值函数分解:VDN、QMIX、QTRAN系列优缺点分析(转载)
  13. 进程隐藏的各种方法 以及分析比较以及实现链接
  14. 音程示范歌曲,lilypond example
  15. 报错WARNING: Ignoring invalid distribution -pencv-python
  16. FPGA设计经验之图像处理
  17. 生产安全事故应急预案
  18. vue.使用popstate监听点击浏览器自带返回按钮
  19. 在面试时,向面试官介绍项目的基本要点
  20. 智能云工厂模式普惠中小企业,千鸟互联或成纸包装产业链“带头大哥”

热门文章

  1. 女生不能学理科?python+数据可视化分析15万考生的成绩,刷新了我的认知
  2. 电力企业信息化系统主要报表展示
  3. java servlet是单例吗_Servlet是单例的吗?
  4. 基于simulink的光伏电站仿真_基于 Carsim 2016 和 Simulink的无人车运动控制联合仿真(二)...
  5. 理解python - 类
  6. docker安装启动mysql5.6_mysql5.6在ubuntu下的docker中安装的方法详解
  7. 年轻人应该做的和不该做的
  8. 定义一个Point类,派生出Circle类,计算各派生类对象的面积Area()
  9. 研究大学生基础课程成绩和专业课程成绩的关系,证明两者之间是否有线性关系
  10. [转]一千行MySQL学习笔记