事件注册与潜在隐患
来源:互联网 发布:淘宝小号怎么找回来 编辑:程序博客网 时间:2024/04/30 14:47
首先看一段模拟代码
输出:
执行这段代码,我们可以看出,Client并没有被垃圾回收。
接下来,我们添加一行代码,再来一次。
输出:
可以看出,Client在取消事件注册后被GC回收。其原因就是如果没有取消事件注册,那么委托链表中的强引用就不会失效,因此GC也就无法回收。相关细节可以参考SDK中有关事件和委托的说明,在此不做详述。
注意:只要一个对象仍然登记有另一个对象的事件,该对象就不可能被执行垃圾回收。建议配合IDisposeable接口,在对象失效前取消事件注册,否则可能造成潜在的内存泄漏。
class EnterpriseComponent
{
public event EventHandler OnEvent;
~EnterpriseComponent()
{
Console.WriteLine("EnterpriseComponent Destroy...");
}
public void DoEvent()
{
if (OnEvent != null)
OnEvent(this, EventArgs.Empty);
}
}
class Client
{
~Client()
{
Console.WriteLine("Client Destroy...");
}
public void OnEvent(object sender, EventArgs e)
{
Console.WriteLine("Event...");
}
}
class Program
{
static void Main(string[] args)
{
EnterpriseComponent eco = new EnterpriseComponent();
Client client = new Client();
// 注册事件
eco.OnEvent += new EventHandler(client.OnEvent);
// 执行事件
eco.DoEvent();
// 模拟Client超出作用范围,等待垃圾回收。
client = null;
// 执行垃圾回收
Console.WriteLine("--GC Strat ---------------");
GC.Collect();
Console.WriteLine("--GC End------------------");
}
}
{
public event EventHandler OnEvent;
~EnterpriseComponent()
{
Console.WriteLine("EnterpriseComponent Destroy...");
}
public void DoEvent()
{
if (OnEvent != null)
OnEvent(this, EventArgs.Empty);
}
}
class Client
{
~Client()
{
Console.WriteLine("Client Destroy...");
}
public void OnEvent(object sender, EventArgs e)
{
Console.WriteLine("Event...");
}
}
class Program
{
static void Main(string[] args)
{
EnterpriseComponent eco = new EnterpriseComponent();
Client client = new Client();
// 注册事件
eco.OnEvent += new EventHandler(client.OnEvent);
// 执行事件
eco.DoEvent();
// 模拟Client超出作用范围,等待垃圾回收。
client = null;
// 执行垃圾回收
Console.WriteLine("--GC Strat ---------------");
GC.Collect();
Console.WriteLine("--GC End------------------");
}
}
输出:
Event...
--GC Strat ---------------
--GC End------------------
--GC Strat ---------------
--GC End------------------
执行这段代码,我们可以看出,Client并没有被垃圾回收。
接下来,我们添加一行代码,再来一次。
static void Main(string[] args)
{
EnterpriseComponent eco = new EnterpriseComponent();
Client client = new Client();
// 注册事件
eco.OnEvent += new EventHandler(client.OnEvent);
// 执行事件
eco.DoEvent();
eco.OnEvent -= new EventHandler(client.OnEvent); // <----- 添加的代码,取消事件注册!!!
// 模拟Client超出作用范围,等待垃圾回收。
client = null;
// 执行垃圾回收
Console.WriteLine("--GC Strat ---------------");
GC.Collect();
Console.WriteLine("--GC End------------------");
}
{
EnterpriseComponent eco = new EnterpriseComponent();
Client client = new Client();
// 注册事件
eco.OnEvent += new EventHandler(client.OnEvent);
// 执行事件
eco.DoEvent();
eco.OnEvent -= new EventHandler(client.OnEvent); // <----- 添加的代码,取消事件注册!!!
// 模拟Client超出作用范围,等待垃圾回收。
client = null;
// 执行垃圾回收
Console.WriteLine("--GC Strat ---------------");
GC.Collect();
Console.WriteLine("--GC End------------------");
}
输出:
Event...
--GC Strat ---------------
Client Destroy...
--GC End------------------
--GC Strat ---------------
Client Destroy...
--GC End------------------
可以看出,Client在取消事件注册后被GC回收。其原因就是如果没有取消事件注册,那么委托链表中的强引用就不会失效,因此GC也就无法回收。相关细节可以参考SDK中有关事件和委托的说明,在此不做详述。
注意:只要一个对象仍然登记有另一个对象的事件,该对象就不可能被执行垃圾回收。建议配合IDisposeable接口,在对象失效前取消事件注册,否则可能造成潜在的内存泄漏。
- 事件注册与潜在隐患
- 引用方式访问STL容器潜在隐患
- 事件注册与删除
- I/O和lock是打断不了的潜在隐患
- 显示调用析构函数潜在隐患分析
- C# 注册事件与通知
- jquery 事件注册 与重复事件处理
- jQuery 事件注册与实时事件
- d3事件(一):注册事件与命名空间
- 注册事件
- C# 在类中如何注册事件与取消事件注册?
- Digg事件凸显Web2.0潜在风险
- Java重写方法与初始化的隐患
- Java重写方法与初始化的隐患
- Java重写方法与初始化的隐患
- 注册事件,反注册事件,匿名事件
- APP安全事件频发,如何第一时间发现隐患?
- Jquery注册服务器控件事件与判断控件的值
- ABAP Get SAP Login Name and Windows Domain User Name.
- 程序员创业,不要把风险带给家人!
- C#编程规范(2008年4月新版)
- ThreadStatic
- C#实现全键盘操作comboBox
- 事件注册与潜在隐患
- 计算两个日期之间的工作天数
- Web—无组件上传的原理
- 用于AVR单片机的USBasp
- C#中常用的经典文件操作方法
- ATL中使用正则表达式
- 我的第一份兼职
- OSCache 的缓冲技术在JSP页面中的使用
- 解析“extern” - keen的专栏 - CSDNBlog