Fork me on GitHub

.net知识和学习方法系列(九)委托异步调用方法a

 委托不但能使事件定阅方法,还有另外一个功能,异步调用方法。
下面看个例子:
 1class Program
 2    {
 3        static void Main(string[] args)
 4        {
 5            Program p = new Program();
 6            DL dl = p.Square;   
 7            //委托的非异步调用
 8            Console.WriteLine(dl.Invoke(2));//或Console.WriteLine(dl(2));
 9            Console.WriteLine(dl.Invoke(4));//Console.WriteLine(dl(4));
10        }

11        public int Square(int i)
12        {
13            Thread.Sleep(3000); //要引入命名空间System.Threading
14            return i * i;
15        }

16    }

17delegate int  DL(int i);
18
 在运行的时候会发现,在三秒后屏幕上打印4,然后再停留三秒后打印16,这就表明,dl.Invoke(2)一但被调用,就会阻塞后面的调用,直到dl.Invoke(2)的返回值返回,然后dl.Invoke(4)才被调用。
有时候我们的业务要求最好不去等待,怎么解决呢?
还好,委托提供了异步调用方法的功能,改告一下上面的代码如下:
 1class Program
 2    {
 3        static void Main(string[] args)
 4        {
 5            Program p = new Program();
 6            DL dl = p.Square;
 7            IAsyncResult asyncresult1 = dl.BeginInvoke(2nullnull);
 8            IAsyncResult asyncresult2 = dl.BeginInvoke(4nullnull);
 9            Console.WriteLine(dl.EndInvoke(asyncresult1));
10            Console.WriteLine(dl.EndInvoke(asyncresult2));          
11        }

12        public int Square(int i)
13        {
14           Thread.Sleep(3000); //要引入命名空间System.Threading
15            return i * i;
16        }

17    }

18    delegate int  DL(int i);
19
 现在,代码的运行几乎是同时的,当4被打印到屏幕上时,16也会被很快打印出来!没中中间的sleep(3000)了。
还有一种方法是,不用关心定义的委托的名字是什么,同样能实现返回参数,如下所地:
 1class Program
 2{         
 3        static void Main(string[] args)
 4        {
 5            Program p = new Program();
 6            DL dl = p.Square;   
 7            IAsyncResult asyncresult1 = dl.BeginInvoke(2nullnull);
 8            IAsyncResult asyncresult2= dl.BeginInvoke(4nullnull);
 9            Console.WriteLine(DateTime.Now.ToString() + ":" +((DL)(((AsyncResult) asyncresult1).AsyncDelegate)).EndInvoke(asyncresult1));  
10            Console.WriteLine(DateTime.Now.ToString() + ":" + ((DL)(((AsyncResult) asyncresult2).AsyncDelegate)).EndInvoke(asyncresult2));
11        }

12        public int Square(int i)
13        {
14           Thread.Sleep(5000); //要引入命名空间System.Threading
15            return i * i;
16        }

17  }

18    delegate int  DL(int i);
19
  注意以下代码:
((DL)(((AsyncResult) asyncresult1).AsyncDelegate)).EndInvoke(asyncresult1)),关没有提及被定义的dl,还有一点就是dl.BeginInvoke(2, null, null)的两个null参数,好,下一篇再介绍!
在上面的例子中,异步的实现就如一个带参数的多线程的实现!可作类同的处理。
posted @ 2008-04-17 08:19  桂素伟  阅读(583)  评论(0编辑  收藏  举报