.Net事件&委托备忘
委托
public delegate xxxx 定义会生成一个委托类的定义,
该类的主要属性是MethodInfo,Target(当Method是静太方法时Target为null)
对委托的执行是通过MethodInfo.Invoke进行反射调用.
该类继承自MulticastDelegate而MulticastDelegate又继承自Delegate
Delegate定义了Combine与Remove两个操作,这两个操作的具体实现是在MulticastDelegate中,MulticastDelegate采用链表形式保留委托链,事件本质上就是对委托的封装
事件可以使用两种方式定义
public delegate void EventHandle()
1.声明方式
public event EventHandle Click
2.属性方式
private static object Event_Click=new object();
public event Click
{
add{...}
remove{...}
}
说明
第一种方式编译后形成如下类似的代码
private EventHandle _Click
public event EventHandle Click
{
add
{...
_Click=Delegate.Combine(ad2, value);
.....
}
remove
{
....
_Click=Delegate.Remove(ad2, value);
....
}
}

private EventHandler SomeEvent1; // Events public event EventHandler SomeEvent { add { EventHandler handler2; EventHandler someEvent = this.SomeEvent1; do { handler2 = someEvent; EventHandler handler3 = (EventHandler) Delegate.Combine(handler2, value); someEvent = Interlocked.CompareExchange<EventHandler>(ref this.SomeEvent1, handler3, handler2); } while (someEvent != handler2); } remove { EventHandler handler2; EventHandler someEvent = this.SomeEvent1; do { handler2 = someEvent; EventHandler handler3 = (EventHandler) Delegate.Remove(handler2, value); someEvent = Interlocked.CompareExchange<EventHandler>(ref this.SomeEvent1, handler3, handler2); } while (someEvent != handler2); } }
上面的代码do{}while(..)是考虑并发时确保每对this.SomeEvent1附值串行进行,Interlocked.c(v0,v1,v2) 会比较v0是否等于v2,如果相等(即进行Combin后this.SomeEvent1没有被其他线程绑定过), 则将v1附值给v0
否则重新绑定,不管v0是否等于v2 interlocked.cxx(v0,v1,v2) 反回的是原v0的值(v0的旧值)
第二种方式内部使用EventHandleList保存,EventHandleList实质上是一个链表实现,在EventHandleList的实现中,绑定到不同事件的处理过程通过key来检索,
绑定到同一个事件的处理过程还是使用委托链来保存.
为什么说使用属性方式实现比较节省内存
原因在于使用属性方式时,定义的key是private static object Eventxxx=new object(); 该字段使用的是static,这样当该组件/控件被大量实例化时他们只使用同一个对象(当然每个实例有一个自己的EventHandleList),而采用声明方式定义时每个实例都会有一组private EventHandle xxx 字段,而每个字段占用4个字节,当组件/控件有大量事件并创建很多实例时(参考下面winform截图),其内存消耗势必比使用属性方式多,
参考资料:
C# 委托链,Delegate.Combine与Delegate.Remove 深究。
也谈事件(Event)
NET 相关问题: 事件存取器
http://www.cnblogs.com/artech/tag/Event/
事件与委托有别, delegate 与 Delegate 相异
EventHandlerList类型内部存储示意图
C#综合揭秘——深入分析委托与事件
http://topic.csdn.net/u/20090710/10/695cf504-f558-425b-b728-723b6d9232ab.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述
2008-09-04 T-SQL 选择某一记录的前后相关记录