委托的使用
| ||||
| ||||
委托在.NET系统中占有很重要的地位,类似于实现C/C++的回调函数的机制,只是委托是类型安全的,而且也线程安全,委托使用极为灵活,用法又很多,学习和使用都很有难度。事件就是基于委托实现的。要能用好委托,解决某些问题非常的优雅。事件就是一个例子,呵呵,比java的事件优雅的不知道多少。委托啊!!
1。通过委托进行异步调用--相当于轻量安全线程 delegate 一个类型其实是继承自Delegate类,因此拥有了BeginInvoke和EndInvoke两个方法,这就为异步执行提供了基础。 2。简化实现--当有多个函数签名一样时很有用 好像跟接口差不多,只是一个通过接口调用,一个通过委托调用,委托更为灵活些 3。多播委托--一个多播委托可以关联多个函数,依次调用执行,事件就是基于多播委托的,需要依次执行的方法序列可以这么做 多播委托继承自MulticastDelegate,这样的委托可以关联多个函数,当然方法签名要一样的,事件就是这样的,多播委托可以用来解决要依次执行的多个方法。 4。实现回调机制--进行回调通知,以及实现像C/C++中的函数回调 当异步调用时要确定是否执行完毕,轮循并不是好的方法,用回调通知,效率上更好,也更为优雅,利用委托回调,可以回调一些API函数,还可以回调客户端的方法等。详细可以参考MSDN 就我知道的就只有这4种用法,用法应该还有很多。 <1>异步调用代码 public class AnsyeDelegateFoo { public int GetSum(int par1, int par2) { return par1 + par2; } } public class AnsyeDelegate /*异步应该是Async*/ { public delegate int dlgAnsyeFoo(int par1,int par2); /** *异步委托调用 **/ public int AnsyeInvoke(int par1,int par2) { dlgAnsyeFoo dlg = new dlgAnsyeFoo((new AnsyeDelegateFoo()).GetSum); /*BeginInvoke调用后立即返回*/ IAsyncResult asyn = dlg.BeginInvoke(par1, par2, null, null); //此处可以添加其他处理代码 while (!asyn.IsCompleted) { //DoSomting Console.WriteLine("正在等待调用结束......."); //此处打印的次数是不定的 } return dlg.EndInvoke(asyn); /** * 可以轮循检查调用是否完成,使用回调通知机制更好 **/ } /** * 同步委托调用 **/ public int SyncInvoke(int par1, int par2) { dlgAnsyeFoo dlg = new dlgAnsyeFoo((new AnsyeDelegateFoo()).GetSum); return dlg(par1, par2); } } <4>事件 class Event { public class MessageEventArgs : EventArgs { /**事件数据类必须继承自EventArgs *并且一般以EventArgs结尾 ***/ public string Message; public MessageEventArgs(string message) { Message = message; } } public delegate void MessageChangedEventHandler(object sender, MessageEventArgs e); /**委托一般以EventHandler结尾 * 参数一般有两个,一个是事件发送者 * 一个是事件数据. **/ public event MessageChangedEventHandler MessageChanged; /*事件的名称应该和委托的名称匹配*/ protected void OnMessageChanged(MessageEventArgs e) {/*这个方法的访问域是protected的,命名在事件名前加On*/ if (MessageChanged != null) { MessageChanged(this, e); } } private string message; public string Message { set { message = value; /*引发这个事件*/ OnMessageChanged(new MessageEventArgs(value)); } get { return message; } } } |