清除控件后,我应该如何停止控件中的计时器?
Posted
技术标签:
【中文标题】清除控件后,我应该如何停止控件中的计时器?【英文标题】:How should I stop timers in my controls after they have been cleared? 【发布时间】:2012-04-02 03:33:37 【问题描述】:我有一个简单的表单,上面有一个 splitviewcontainer,左侧是菜单,右侧包含一个或多个控件。
可以在 RHS 上加载的控件之一包含一个计时器,用于每隔几秒刷新一次数据。
如果我在右侧使用 Controls.Clear(),控件将不再显示,但我认为它没有被释放,因为计时器仍在触发(我可以看到在日志中进行的数据库调用)。
因此,我的问题是,当控件从显示中删除时,我应该如何清理它?清除控件时调用哪个事件/方法?
【问题讨论】:
你能覆盖可见属性并在其上启动和停止计时器吗? 或监听父级变化? 您是在问如何停止计时器以触发 elasped/tick 事件,或者如何处理面板中的控件? 史蒂夫,定时器在我面板中的一个控件内,我希望当控件不再在面板中时定时器停止触发,因为 Panel.Controls.Clear();我的假设是 Clear 会自动处理内部的控件,但事实并非如此。 您使用的是 WPF 还是 Windows 窗体? 【参考方案1】:您应该在控件上调用适当的Dispose()
方法。
您可以使用扩展方法来执行此操作,请参阅 Hans Passant 的this 回答。
可以在 RHS 上加载的控件之一包含一个计时器,用于每隔几秒刷新一次数据。
现在,您可能在这里遇到了竞争条件。当您调用尚未创建的Clear()
扩展方法时,计时器可能需要回调。如果您的计时器回调函数可能会导致您的应用程序中的数据损坏,您将不得不这样做。
Timer.Stop();
Timer.Tick -= Timer_Tick(TimerCallback);
Timer.Dispose();
现在另一个问题是 - 你可以隐藏这些控件吗?是否存在阻止您这样做的约束?
【讨论】:
隐藏控件不就是内存泄漏问题吗? @AdamKing:是什么让你得出这个结论? 我的理解是 Hide 保持控件是内存,只是不显示它。不是这样吗? @AdamKing:确实如此。但是当你关闭这个表单时,GC 会负责清理资源。从您的问题中不清楚此表单的生命周期是什么,或者控件将被创建/销毁多少次。在某些情况下,隐藏它可能更容易。 我不打算在相当长的时间内关闭此表单,因此 GC 将没有机会为我解决问题。【参考方案2】:这段代码应该工作
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
我很乐意回答任何疑问
【讨论】:
【参考方案3】:我会使用扩展方法而不是 Clear()。并循环遍历子控件并专门处理它们。如果某些控件没有 IDispose(但应该有)导致这种情况,那么您可以在循环中专门捕获它们并调用任何方法阻止它们,然后再通过最终清除销毁它们。
【讨论】:
以上是关于清除控件后,我应该如何停止控件中的计时器?的主要内容,如果未能解决你的问题,请参考以下文章