C# 使用事件处理程序动态加载用户控件-取消注册
我有一个带有面板的窗体,在该窗体上动态加载多个用户控件。我处理每个控件的事件C# 使用事件处理程序动态加载用户控件-取消注册,c#,asp.net,events,user-controls,event-handling,C#,Asp.net,Events,User Controls,Event Handling,我有一个带有面板的窗体,在该窗体上动态加载多个用户控件。我处理每个控件的事件 UserControl userControl1 = LoadControl("control.ascx") as UserControl; userControl1.Event += new ControlEventHandler(userControl_Event); this.Panel.Controls.Add(userControl1); UserControl userControl2 = LoadCon
UserControl userControl1 = LoadControl("control.ascx") as UserControl;
userControl1.Event += new ControlEventHandler(userControl_Event);
this.Panel.Controls.Add(userControl1);
UserControl userControl2 = LoadControl("control.ascx") as UserControl;
userControl2.Event += new ControlEventHandler(userControl_Event);
this.Panel.Controls.Add(userControl2);
...
现在,当我去掉面板上的控件时,我只需执行一个
this.Panel.Controls.Clear();
Clear()函数是否负责清除事件,或者我应该这样做
foreach(Control control in this.Panel.Controls)
{
UserControl userControl = control as UserControl;
if(userControl != null)
{
userControl -= userControl_Event;
}
}
在我清除()面板的内容之前
基本上,我正在寻找一种方法来动态加载用户控件并处理它们的事件,而在清除它们时不会造成泄漏
谢谢
编辑:
因为我的控件是在页面的Page_Init事件中创建的(每次都是动态加载的),所以说它们的寿命不能超过页面的寿命是正确的吗?
据我所知,回发邮件后控件不存在。每次都会创建一个新的。因此,我不应该取消注册该事件,因为该对象在下一页加载时甚至不存在。正确吗?垃圾收集器应该能够收集这些控件,而无需您注销它们即使在清除收集后,页面仍将保留对动态实例化控件的引用,这将阻止在收集页面之前收集控件 在这种特殊情况下,这会很好,因为页面的生命周期非常短 但是,如果这是一个windows窗体应用程序,那么在释放窗体之前,内存实际上会泄漏
一般来说,在释放事件所指向的对象时取消订阅事件是一个好主意,因为这是绝大多数.net内存泄漏的来源。MSDN上的此页回答了您的问题: 引用它: 重要 调用Clear方法不会导致错误 从内存中删除控制手柄。 必须显式调用Dispose 方法来避免内存泄漏
可以正确地说,动态加载的UserControl的寿命不能超过它所属的页面的寿命。但是,如果从页面控件集合中删除web控件并将其分配给会话变量(例如,会话变量)可能会导致web控件的寿命长于页面,则我们不能说这是真的。所以这并不总是正确的 如果使用短生命期对象(如页面、用户控件或web控件等)的方法订阅长寿命对象的事件(如单例对象或asp.net中与应用程序、会话和缓存一起存储的对象),则应取消订阅事件,这一点很重要 比如说
UserControl uc = LoadControl("control.ascx") as UserControl;
SomeObject so=Session["SomeObject"] as SomeObject;
If(so!=null)
{
so.SomeEvent += new SomeEventHandler(uc.SomeMethod);
}
在这里,它应该从事件中取消订阅,以避免导致内存泄漏
最终,您不必担心您案例中的注册事件。它们将由垃圾收集器收集 您在面板中调用
控件。清除的事实足以证明您还应该注销事件
为此,您可以使用重写的Clear
方法中的注销代码创建自己的控件集合,而不是创建自己的面板,该面板使用从重写的Controls
属性获取程序返回的新集合