http://www.cnblogs.com/panjun-Donet/archive/2009/03/03/1284700.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个公用属性

下面写一个标准的例子


class Program

    {

        static void Main(string[] args)

        {

            number num = new number();

            sum numberadd = new sum(num.numberAdd);

            AsyncCallback numberback = new AsyncCallback(num.CallbackMethod2);

            numberadd.BeginInvoke(,,numberback,numberadd);

            Console.WriteLine("The sum is:");

            Console.WriteLine(num.m);

        }

    }

  //定义一个执行加法的委托
    public delegate int sum(int a, int b);

    public class number

    {

       ;

       //定义一个实现此委托签名的方法
       public int numberAdd(int a, int b)

       {

           int c = a + b;

           return c;

       }

       //定义一个与.net framework定义的AsyncCallback委托相对应的回调方法
       public  void CallbackMethod2(IAsyncResult ar2)

       {

           sum s = (sum)ar2.AsyncState;

           int number = s.EndInvoke(ar2);

           m = number;

          

       }

    }

实际上,发起和完成.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-利用回调函数(这个方法比较靠谱 见http://blog.csdn.net/onafioo/article/details/44356035
如果启动异步调用的线程不需要处理调用结果,则可以在调用完成时执行回调方法
要使用回调方法,必须将代表该方法的AsyncCallback委托传递给BeginInvoke
再次修改代码43-46这几行代码:
AsyncEventHandler asy = new AsyncEventHandler(c.Event1);
asy.BeginInvoke(new AsyncCallback(c.CallbackMethod),asy);
c.Event2();

异步编程(AsyncCallback委托,IAsyncResult接口,BeginInvoke方法,EndInvoke方法的使用小总结)的更多相关文章

  1. 用委托(Delegate)的BeginInvoke和EndInvoke方法操作线程

    让我们首先了解下什么时候用到C#异步调用: .NET Framework 允许您C#异步调用任何方法.定义与您需要调用的方法具有相同签名的委托:公共语言运行库将自动为该委托定义具有适当签名的Begin ...

  2. 【C#】用委托(Delegate)的BeginInvoke和EndInvoke方法操作线程

    让我们首先了解下什么时候用到C#异步调用: .NET Framework 允许您C#异步调用任何方法.定义与您需要调用的方法具有相同签名的委托:公共语言运行库将自动为该委托定义具有适当签名的Begin ...

  3. C#线程系列讲座(1):BeginInvoke和EndInvoke方法

    一.C#线程概述 在操作系统中一个进程至少要包含一个线程,然后,在某些时候需要在同一个进程中同时执行多项任务,或是为了提供程序的性能,将要执行的任务分解成多个子任务执行.这就需要在同一个进程中开启多个 ...

  4. delegate 中的BeginInvoke和EndInvoke方法

    开发语言:C#3.0 IDE:Visual Studio 2008 一.C#线程概述 在操作系统中一个进程至少要包含一个线程,然后,在某些时候需要在同一个进程中同时执行多项任务,或是为了提供程序的性能 ...

  5. 转:C#线程系列讲座(1) BeginInvoke和EndInvoke方法

    转载自:http://www.cnblogs.com/levin9/articles/2319248.html 开发语言:C#3.0IDE:Visual Studio 2008本系列教程主要包括如下内 ...

  6. 黄聪:C#多线程教程(1):BeginInvoke和EndInvoke方法,解决主线程延时Thread.sleep柱塞问题(转)

    开发语言:C#3.0 IDE:Visual Studio 2008 本系列教程主要包括如下内容: 1.  BeginInvoke和EndInvoke方法 2.  Thread类 3. 线程池 4. 线 ...

  7. C# BeginInvoke和EndInvoke方法

    转载自:BeginInvoke和EndInvoke方法 IDE:Visual Studio 2008 本系列教程主要包括如下内容:1. BeginInvoke和EndInvoke方法 2. Threa ...

  8. BeginInvoke和EndInvoke方法

    本系列教程主要包括如下内容:1. BeginInvoke和EndInvoke方法 2. Thread类 3. 线程池 4. 线程同步基础 5. 死锁 6. 线程同步的7种方法 7. 如何在线程中访问G ...

  9. 委托的BeginInvoke和EndInvoke方法

    .NET Framework 允许异步调用任何方法,为了实现异步调用目标,需要定义与被调用方法具有相同签名的委托.公共语言运行时会自动使用适当的签名为该委托定义 BeginInvoke 和 EndIn ...

随机推荐

  1. PowerDesigner逆向工程,从SQL Server数据库生成Physical Model -----数据源方式

    1.File-Reverse Engineer-Database 2.DBMS选择SQL Server 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 一路Next..... ...

  2. 1069: [SCOI2007]最大土地面积

    1069: [SCOI2007]最大土地面积 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 2961  Solved: 1162[Submit][Sta ...

  3. spark 划分stage Wide vs Narrow Dependencies 窄依赖 宽依赖 解析 作业 job stage 阶段 RDD有向无环图拆分 任务 Task 网络传输和计算开销 任务集 taskset

    每个job被划分为多个stage.划分stage的一个主要依据是当前计算因子的输入是否是确定的,如果是则将其分在同一个stage,从而避免多个stage之间的消息传递开销. http://spark. ...

  4. cocos2d-js 运行动画

    1.添加动画缓存 //添加动画缓存 cc.spriteFrameCache.addSpriteFrames(res.bug_plist); this.spriteSheet = new cc.Spri ...

  5. Jquery AJAX如何使用Promise/Deferred实现顺序执行?

    有的时候有我有N个AJAX请求,第下个请求可能要依赖上个请求的返回值, 可以用 $.ajax("test1.php").then(function(data) { // data ...

  6. [数据挖掘课程笔记]关联规则挖掘 - Apriori算法

    两种度量: 支持度(support)  support(A→B) = count(AUB)/N (N是数据库中记录的条数) 自信度(confidence)confidence(A→B) = count ...

  7. wait()和notify()

    从https://www.cnblogs.com/toov5/p/9837373.html 可以看到他的打印是一片一片的,这边博客介绍怎么避免掉 使用notify 和 wait的时候 要注意 是在sy ...

  8. hadoop内存分配方案

    Configuration File   Configuration Setting Value Calculation        8G VM (4G For MR)    yarn-site.x ...

  9. 理解HTML解析过程

    浏览器解析html的过程是:接受网络数据->将二进制码变成字符->将字符变为unicode code points.->tokenizer ->tree constructor ...

  10. 我的CSDN博客

    从csdn搬过来的: csdn地址:http://blog.csdn.net/WR_technology