梳理delegate相关概念
一、前言
可能项目规模较小,项目中除了增删改查就只剩下业务流程,以前都没怎么弄明白的东西时间长了就越发的模糊了...
二、使用场景
MSDN:delegate 是一种可用于封装命名或匿名方法的引用类型。 委托类似于 C++ 中的函数指针;但是,委托是类型安全和可靠的。
- 匿名方法
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 }
- 委托类型
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 }
- 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 Publisher 26 { 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 }
- 异步委托
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 }
-
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 }