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. Android 向右滑动销毁(finish)Activity, 随着手势的滑动而滑动的效果

    http://blog.csdn.net/xiaanming/article/details/20934541

  2. 九度OJ 1126:打印极值点下标 (基础题)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:4613 解决:1646 题目描述: 在一个整数数组上,对于下标为i的整数,如果它大于所有它相邻的整数, 或者小于所有它相邻的整数,则称为该整 ...

  3. wepy原理研究

    像VUE一样写微信小程序-深入研究wepy框架 https://zhuanlan.zhihu.com/p/28700207 wepy原理研究 虽然wepy提升了小程序开发体验,但毕竟最终要运行在小程序 ...

  4. Java,获取文件的Base64字符串,解码Base64字符串还原文件

    在jdk1.8以前,获取文件Base64字符串需要用到第三方库,从1.8开始,Java中引入了Base64相关的类 以下是代码示例 获取文件的Base64编码字符串 import java.io.Fi ...

  5. tornado安全应用之cookie

    目前大多数服务器判断用户是否登录一般通过session机制,Tornado 通过 set_secure_cookie 和 get_secure_cookie 方法直接支持了这种功能.原理类似于sess ...

  6. sdutoj 2373 Black and white painting( 规律统计计算 3Y )

    Black and white painting 题目描述 You are visiting the Centre Pompidou which contains a lot of modern pa ...

  7. 2017广东工业大学程序设计竞赛 E倒水(Water)

    题目链接:http://www.gdutcode.sinaapp.com/problem.php?cid=1057&pid=4 题解: 方法一:对n取2的对数: 取对数的公式:s = log( ...

  8. html5--3.18 新增的output元素

    html5--3.18 新增的output元素 学习要点 了解output元素的用法 output元素:数据的输出 output元素是HTML5新增的元素,用来设置不同数据的输出 output元素的输 ...

  9. 用php描述顺序查找

    //顺序查找(数组里查找某个元素) $arr = array(3,55,45,2,67,76,6.7,-65,85,4); function seq_sch($array, $k){ for($i=0 ...

  10. WPF Combo box 获取选择的Tag

    string str1 = ((ComboBoxItem)this.cboBoxRate1553B.Items[this.cboBoxRate1553B.SelectedIndex]).Tag.ToS ...