c#异步编程

来源:互联网 发布:美国公开政府数据法案 编辑:程序博客网 时间:2024/04/27 15:07
同步方法和异步方法的区别

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

异步编程概览

.NET Framework 允许您异步调用任何方法。定义与您需要调用的方法具有相同签名的委托;公共语言运行库将自动为该委托定义具有适当签名

的 BeginInvoke 和 EndInvoke 方法。

BeginInvoke 方法用于启动异步调用。它与您需要异步执行的方法具有相同的参数,只不过还有两个额外的参数(将在稍后描述)。

BeginInvoke 立即返回,不等待异步调用完成。
BeginInvoke 返回 IasyncResult,可用于监视调用进度。

EndInvoke 方法用于检索异步调用结果。调用 BeginInvoke 后可随时调用 EndInvoke 方法;如果异步调用未完成,EndInvoke 将一直阻塞到

异步调用完成。EndInvoke 的参数包括您需要异步执行的方法的 out 和 ref 参数(在 Visual Basic 中为 <Out> ByRef 和 ByRef)以及由

BeginInvoke 返回的 IAsyncResult。

四种使用 BeginInvoke 和 EndInvoke 进行异步调用的常用方法。调用了 BeginInvoke 后,可以:

1.进行某些操作,然后调用 EndInvoke 一直阻塞到调用完成。
2.使用 IAsyncResult.AsyncWaitHandle 获取 WaitHandle,使用它的 WaitOne 方法将执行一直阻塞到发出 WaitHandle 信号,然后调用

EndInvoke。这里主要是主程序等待异步方法,等待异步方法的结果。
3.轮询由 BeginInvoke 返回的 IAsyncResult,IAsyncResult.IsCompeted确定异步调用何时完成,然后调用 EndInvoke。此处理个人认为与
相同。
4.将用于回调方法的委托传递给 BeginInvoke。该方法在异步调用完成后在 ThreadPool 线程上执行,它可以调用 EndInvoke。这是在强制装

换回调函数里面IAsyncResult.AsyncState(BeginInvoke方法的最后一个参数)成委托,然后用委托执行EndInvoke。
警告   始终在异步调用完成后调用 EndInvoke。

以上有不理解的稍后可以再理解。

 

例子

1)先来个简单的没有回调函数的异步方法例子

请再运行程序的时候,仔细看注释,对理解很有帮助。还有,若将注释的中的两个方法都同步,你会发现异步运行的速度优越性。

 

using System;

 
namespace ConsoleApplication1
 
{
     
class Class1
     
{
         
//声明委托
         public delegate void AsyncEventHandler();
 
         
//异步方法
         void Event1()
        
{
            Console.WriteLine(
"Event1 Start");
            System.Threading.Thread.Sleep(
4000);
            Console.WriteLine(
"Event1 End");
        }


        
// 同步方法
        void Event2()
        
{
            Console.WriteLine(
"Event2 Start");
            
int i=1;
            
while(i<1000)
            
{
                i
=i+1;
                Console.WriteLine(
"Event2 "+i.ToString());
            }

            Console.WriteLine(
"Event2 End");
        }


        [STAThread]
        
static void Main(string[] args)
        
{
            
long start=0;
            
long end=0;
            Class1 c 
= new Class1();
            Console.WriteLine(
"ready");
            start
=DateTime.Now.Ticks;

            
//实例委托
            AsyncEventHandler asy = new AsyncEventHandler(c.Event1);
            
//异步调用开始,没有回调函数和AsyncState,都为null
            IAsyncResult ia = asy.BeginInvoke(nullnull);
            
//同步开始,
            c.Event2();
            
//异步结束,若没有结束,一直阻塞到调用完成,在此返回该函数的return,若有返回值。

           
            asy.EndInvoke(ia);

            
//都同步的情况。
            
//c.Event1();
            
//c.Event2();
           
            end 
=DateTime.Now.Ticks;
            Console.WriteLine(
"时间刻度差="+ Convert.ToString(end-start) );
            Console.ReadLine();
        }

    }

}