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. 九度OJ 1086:最小花费 (DP)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:3960 解决:819 题目描述: 在某条线路上有N个火车站,有三种距离的路程,L1,L2,L3,对应的价格为C1,C2,C3.其对应关系如下 ...

  2. what??|诞生才一年的BCH竟面临硬分叉的抉择

    BCH才刚过一周岁生日一个星期,BCH社区的主力之一Bitcoin ABC(BCH全网接近三分之二节点运行的软件系统由Bitcoin ABC开发)就搅动了社区的涟漪.8月8号,Bitcoin ABC公 ...

  3. Redis学习笔记(1):Redis的说明与安装

    Redis学习笔记(1):Redis说明的安装 说明 什么是Redis REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-va ...

  4. SVN版本控制中.a无法提交问题

    1.首先xcode是默认忽略.a文件的.改变方法如下: 1⃣️. 打开终端,  在命令行中输入: vi ~/.subversion/config  来打开配置文件.2⃣️. 然后, 在[miscell ...

  5. 内核中led触发器实例【转】

    本文转载自:http://blog.csdn.net/yuanlulu/article/details/6438847 ======================================== ...

  6. 电脑设备对于IT人员,犹如武器对于士兵

    本人做了多年Softwarer,写些感受. 比我们早的老一代程序员更是用自己的健康总结了一些经验. 先说关于健康方面: 程序员要长期坐着,这对健康损害很大,颈椎腰椎,心肺能力都会衰减.以前只是听说,自 ...

  7. win7下使用source insight,没有Courier字体

    http://hi.baidu.com/raoxj/item/0e3a3a3b2461c5be134b14fa 1. “控制面板:--->“字体”--->找到Courier New(建议用 ...

  8. Windows服务的快速搭建与调试(C#图解)

    Windows服务的快速搭建与调试(C#图解)   目录 一.什么是Windows 服务? 二.创建Windows 服务与安装/卸载批处理. 三.调试Windows 服务. 正文 一.什么是Windo ...

  9. CodeForces813E:Army Creation (主席树---上一题的加强版)

    As you might remember from our previous rounds, Vova really likes computer games. Now he is playing ...

  10. https证书自签

         https               http over ssl = https 443/tcp                 ssl: v3                 tls: ...