C#每天进步一点--异步编程模式

C#可以有一个简单易用的机制用于异步执行方法,那就是委托。下面我介绍三种模式,对于这三种模式来说,原始线程都发起了一个异步方法,然后做一些其他处理。然而这些模式不同的是,原始线程获取发起的线程已经完成的消息的方式。

1:在等待一直到完成(wait-nutil-done)模式。

  在发起了异步方法以及做了一些其他处理之后,原始线程就中断并且等异步方法完成之后再继续。

class Program
{
    private delegate int  MyDel(int a);
 
    public static int MyMenthod(int a)
    {
        for (int i = 0; i < 1000; i++)
        {
            a++;
        }
        return a;
    }
 
    static void Main(string[] args)
    {
        var del = new MyDel(MyMenthod);
        Console.WriteLine("Before BeginInvoke");
        IAsyncResult iar = del.BeginInvoke(5, null, null);
        Console.WriteLine("After BeginInvoke");
 
        Console.WriteLine("Doing stuff");
 
        long result = del.EndInvoke(iar);
 
        Console.WriteLine("结果为{0}",result);
    }
}

运行结果为

2:轮询模式(polling)。

  原始线程定期检查发起的线程是否完成,如果没有则可以继续做其他的事情。上代码

class Program
  {
      private delegate int  MyDel(int a);
 
      public static int MyMenthod(int a)
      {
          for (int i = 0; i < 1000; i++)
          {
              a++;
          }
          Thread.Sleep(3000);
          return a;
      }
 
      static void Main(string[] args)
      {
          var del = new MyDel(MyMenthod);
 
          IAsyncResult iar = del.BeginInvoke(5,null,null);
          Console.WriteLine("After BeginInvoke");
 
          while (!iar.IsCompleted)
          {
              Console.WriteLine("还没处理完");
 
              Thread.Sleep(2000);
              Console.WriteLine("继续处理其他事情");
          }
          Console.WriteLine("异步执行完成");
          long result = del.EndInvoke(iar);
          Console.WriteLine("结果为{0}",result);
      }
  }


  运行结果为:

3:回调模式(callbacl)。

  原始线程一直执行,无需等待或检查发起的线程是否完成,在发起的线程中的引用方法完成之后,发起的线程就会调用回调方法,由回调方法在调用EndInvoke之前处理异步方法的结构。上代码

class Program
 {
     private delegate int  MyDel(int a);
 
     public static int MyMenthod(int a)
     {
         for (int i = 0; i < 1000; i++)
         {
             a++;
         }
         return a;
     }
     public static void CallBack(IAsyncResult iar)
     {
         AsyncResult ar = iar as AsyncResult;
         MyDel del = (MyDel)ar.AsyncDelegate;
         long r = del.EndInvoke(iar);
         Thread.Sleep(2000);
         Console.WriteLine("结果出来了,为{0}", r);
     }
     static void Main(string[] args)
     {
         var del = new MyDel(MyMenthod);
 
         Console.WriteLine("After BeginInvoke");
         IAsyncResult iar= del.BeginInvoke(5, CallBack, del);
 
         Console.WriteLine("Doing More Work In Main");
         Thread.Sleep(5000);
     }
 }

  运行结果为:

回调方法的签名和返回类型必须和AsyncCallbacl委托类型所描述的形式一致。它需要方法接受一个IAsyncResult作为参数并且返回类型是void,如下:

 void AsyncCallback(IAsyncResult iar)

我们有多种方式可以为BeginInvoke方法提供回调方法,由于BeginInvoke中的callback参数是AsyncCallback类型的委托,我们可以以委托形式提供,我们也可以只提供回调方法名称,让编译器为我们创建委托,两种形式是等价的。

IAsyncResult iar1 = del.BeginInvoke(5,new AsyncCallback(CallWhenDone),null);

IAsyncResult iar2 = del.BenginInvoke(5,CallWhenDone,null);



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值