1、委托 多播委托
delegate :是对函数的抽象,Delegate 实例在会被编译成一个类型,反编译可以看到委托是一个类型,这个类型的实例是委托链,可以添加参数和返回值符合要求的函数。
委托类型里面定义了3个函数,invoke 同步调用委托,按照委托链的顺序执行所有函数。begin invoke 和end invoke对应异步调用
下图是委托和多播委托的原理:(委托的常用知识点还有 Fun<> action 系统委托,lambda表达式 和匿名方法
多播委托的返回值
那么如何取得多播委托的所有方法的返回值呢?
多播委托的反编译效果:
可以看到多播委托添加处理方法时 实际是在new新的委托对象,只是通过combine的方法来更新委托数组(印证了图中的结论)
委托的反编译IL代码:
可以看到委托实际是一个类型 ,有3个方法,invoke ,begin invoke 和end invoke
2、委托的BeginInvoke 和EndInvoke详解
众所周知,委托(delegate)实际是一个类型 ,里面有 invoke,beginInvoke ,endInvoke 3个方法:
其中invoke代表委托的同步调用 , begininvoke 和endinvoke 配合实现委托的异步调用。
本质是执行BeginInvoke时, 开启线程池线程来执行委托
我们通过几个实例来理解委托的异步调用
实例1:没有回调函数的异步调用
实例2 :有回调函数的异步委托
结论1:回调函数是begininvoke方法执行完成后,在异步线程中执行的。
结论2:如图 beginInvoke的第4个参数是传个回调函数参数ar的AsyncState 属性
在回调函数中如何取得委托 返回值等等:
查看dotnet源码后发现Delegate 实际上市一个抽象类:
对于Delegate为什么能够实例化需要进一步的理解
事件Event
事件是特殊的委托实例(综上所述 Delegate 实例会被编译为类型) 特殊在事件只能在Delegate 类内部调用
查看.net 源码发现delegate的CreateDelegate ,event可能有type参数中 做过特殊处理