Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用事件处理程序动态加载用户控件-取消注册_C#_Asp.net_Events_User Controls_Event Handling - Fatal编程技术网

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
属性获取程序返回的新集合