C# 清除控件中的计时器后,应如何停止它们?

C# 清除控件中的计时器后,应如何停止它们?,c#,winforms,timer,C#,Winforms,Timer,我有一个简单的表单,上面有一个splitviewcontainer,左侧是一个菜单,右侧包含一个或多个控件 RHS上可以加载的其中一个控件包含一个计时器,用于每隔几秒钟刷新其数据 如果我在右侧使用Controls.Clear(),控件将不再显示,但我假设它尚未被释放,因为计时器仍在启动(我可以在日志中看到数据库调用) 因此,我的问题是,当控件从显示中移除时,我应该如何清理它?清除控件时调用哪个事件/方法?您应该在控件上调用相应的Dispose()方法 您可以使用扩展方法来实现这一点,请参见Han

我有一个简单的表单,上面有一个splitviewcontainer,左侧是一个菜单,右侧包含一个或多个控件

RHS上可以加载的其中一个控件包含一个计时器,用于每隔几秒钟刷新其数据

如果我在右侧使用Controls.Clear(),控件将不再显示,但我假设它尚未被释放,因为计时器仍在启动(我可以在日志中看到数据库调用)


因此,我的问题是,当控件从显示中移除时,我应该如何清理它?清除控件时调用哪个事件/方法?

您应该在控件上调用相应的
Dispose()
方法

您可以使用扩展方法来实现这一点,请参见Hans Passant的答案

RHS上可以加载的其中一个控件包含一个计时器,用于每隔几秒钟刷新其数据

现在,你可能有一个比赛条件。当您调用尚未创建的
Clear()
extension方法时,计时器可能需要回调。如果计时器回调函数可能导致应用程序中的数据损坏,则必须执行以下操作

Timer.Stop();
Timer.Tick -= Timer_Tick(TimerCallback);
Timer.Dispose(); 

现在,另一个问题是-您是否可以隐藏这些控件?是否存在阻止您这样做的约束条件?

这段代码应该可以工作

public Form1()
{
    InitializeComponent();
    UserControl cc = new UserControl();
    Panel pp = new Panel();
    pp.Controls.Add(cc);
    pp.ControlRemoved += new ControlEventHandler(pp_ControlRemoved);
    pp.Controls.Clear();
}

void pp_ControlRemoved(object sender, ControlEventArgs e)
{
    var control = sender as MyVerySpecialControl;
    if (control != null)
    {
        //stop timers or unassign events
    }
}

我很乐意回答任何疑问

我会使用扩展方法而不是Clear()。和循环子控件,并专门处理它们。如果某些控件没有导致此问题的IDispose(但应该有),然后,您可以在循环中捕获它们,并调用任何方法来停止它们,然后用最终清除来销毁它们。

您可以覆盖visible属性并启动和停止该属性上的计时器吗?或者侦听父项已更改吗?您是问如何停止计时器以触发elasped/tick事件,还是如何在您的系统中处理控件panel?Steve,计时器在我的面板中的一个控件内,我希望当控件由于panel.Controls.Clear()而不再在面板中时,计时器停止启动;我的假设是Clear会自动处理内部的控件,但事实并非如此。您使用的是WPF或Windows窗体吗?隐藏控件不仅仅是内存泄漏问题吗?@AdamKing:是什么让您得出这样的结论?我的理解是隐藏控件是内存,只是不显示它。“不是这样吗?”阿达姆金:是的。但是当您关闭此表单时,GC将负责清理资源。您的问题不清楚此表单的生命周期是什么,或者控件将被创建/销毁多少次。在某些情况下,隐藏它可能更容易。我不打算在相当长的时间内关闭此表单,因此GC将没有机会为我解决问题。