你的位置:首页 > ASP.net教程

[ASP.net教程]梳理delegate相关概念


一、前言

  可能项目规模较小,项目中除了增删改查就只剩下业务流程,以前都没怎么弄明白的东西时间长了就越发的模糊了...

二、使用场景

  MSDN:delegate 是一种可用于封装命名或匿名方法的引用类型。 委托类似于 C++ 中的函数指针;但是,委托是类型安全和可靠的。

  1. 匿名方法
    1 static void Main(string[] args)2 {3   TestAnonymousMethod(delegate(string i) { return Convert.ToInt32(i); });4 }5 6 static int TestAnonymousMethod(Func<string, int> func)7 {8   return func("10");9 }

  2. 委托类型
     1 //定义委托类型 2 delegate bool CompareDelegate(int i, int j); 3  4 static void Main(string[] args) 5 { 6   //声明对象 7   //CompareDelegate cd = new CompareDelegate(Compare); 8   CompareDelegate cd = Compare; 9   Console.WriteLine(cd(10, 20));10 11   TestDelegate(Compare);12 }13 14 //与委托类型签名相同的方法15 static bool Compare(int i, int j)16 {17   return i > j;18 }19 20 //委托声明方法形参,将方法以参数传递21 static void TestDelegate(CompareDelegate cd)22 {23   Console.WriteLine(cd(20, 10));24 }

  3. event修饰委托(写这篇博客就是为了这一个节点...)
    MSDN:event 关键字用于在发行者类中声明事件。事件是特殊类型的多路广播委托,仅可从声明它们的类或结构(发行者类)中调用。 如果其他类或结构订阅了该事件,则当发行者类引发该事件时,会调用其事件处理程序方法。
    曾今天真的以为delegate与event是同级别的关键词,直到昨天整理资料才恍然大悟,delegate跟event半毛钱关系都没有。delegate相当于关键字class,使用关键字delegate定义委托类型,然后使用委托类型声明委托变量,声明变量时可用event修饰。
     1 class Program 2 { 3   delegate bool CompareDelegate(int i, int j); 4  5   static void Main(string[] args) 6   { 7     Publisher p = new Publisher(); 8     p.Sample = Method; 9     p.Sample += Method; //注册第二个方法10 11     //event仅可在声明它的类或结构使用=注册事件,防止外部注册事件时不小心覆盖了其他地方注册的事件方法12     p.SampleEvent += Method;13     p.RaiseSampleEvent();14 15     //event修饰后的委托只能在声明它的类或结构中调用,没有event修饰的的委托可在外部调用16     p.Sample("外部测试调用");17   }18 19   static void Method(string msg)20   {21     Console.WriteLine(msg);22   }23 }24 25 public class Publisher26 {27   public delegate void SampleEventHandler(string msg);28 29   //不使用event修饰30   public SampleEventHandler Sample;31 32   //使用event修饰33   public event SampleEventHandler SampleEvent;34 35   public virtual void RaiseSampleEvent()36   {37     if (Sample != null)38     {39       Sample("不使用event修饰");40     }41 42     if (SampleEvent != null)43     {44       SampleEvent("使用event修饰");45     }46   }47 }

  4. 异步委托

    BeginInvoke 方法启动异步调用。该方法具有与你要异步执行的方法相同的参数,另加两个可选参数。第一个参数是一个AsyncCallback委托,此委托引用在异步调用完成时要调用的方法。第二个参数是一个用户定义的对象,该对象将信息传递到回调方法。 BeginInvoke 将立即返回,而不会等待异步调用完成。 BeginInvoke 返回可用于监视异步调用的进度的 IAsyncResult。
    EndInvoke 方法用于检索异步调用的结果。它可以在调用 BeginInvoke 之后的任意时间调用。如果异步调用尚未完成,那么EndInvoke将阻止调用线程,直到完成异步调用。EndInvoke的参数包括您需要异步执行的方法的out和ref 参数以及由 IAsyncResult 返回的 BeginInvoke。

     1 static void Main(string[] args) 2 { 3   Console.WriteLine("主线程开始"); 4   Action<string> act = msg => 5   { 6     Thread.Sleep(1000); 7     Console.WriteLine(msg); 8   }; 9   //异步调用10   IAsyncResult result = act.BeginInvoke("委托方法", null, null);11 12   Console.WriteLine("主线程。。。");13 14   //异步调用完成返回15   act.EndInvoke(result);16 17   Console.WriteLine("主线程结束");18 }
      
  5.  1 static void Main(string[] args) 2 { 3   Console.WriteLine("主线程开始"); 4   Action<string> act = msg => 5   { 6     Thread.Sleep(1000); 7     Console.WriteLine(msg); 8   }; 9 10   //异步调用,不阻塞进程11   act.BeginInvoke("委托方法", ar =>12   {13     Action<string> handler = (Action<string>)((AsyncResult)ar).AsyncDelegate;14     handler.EndInvoke(ar);15     Console.WriteLine(ar.AsyncState);16   }, "AsyncState:OK");17   Console.WriteLine("主线程结束");18   Thread.Sleep(2000);19 }