是什么让这个计时器在范围内?匿名方法?

时间:2010-06-02 14:05:47

标签: c# events garbage-collection anonymous-methods

确定,

所以我有一个方法可以在有人点击Silverlight应用程序中的Icon时触发,如下所示:

    private void Logo_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        e.Handled = true;
        ShowInfo(true);

        DispatcherTimer autoCloseTimer = new DispatcherTimer();
        autoCloseTimer.Interval = new TimeSpan(0, 0, 10);
        autoCloseTimer.Tick +=new EventHandler((timerSender,args) => 
            {
                autoCloseTimer.Stop();
                ShowInfo(false);
            });
        autoCloseTimer.Start();
    }

意味着发生的是ShowInfo()方法打开一个包含公司信息的框,并且调度计时器会在所述时间跨度后自动关闭它。这一切都有效......

但我不确定是因为调度计时器是本地var,在Logo_MouseLeftButtonUp方法完成之后,在匿名方法被触发之前,有什么能够保持调度计时器被引用而不能用于GC集合? / p>

它是匿名方法中ShowInfo()方法的引用吗?

感觉就像我应该更深入地了解一些事情,因为我可以想象使用事件等,这样就可以很容易地创建漏洞。

希望这一切都有意义!

安迪。

2 个答案:

答案 0 :(得分:9)

当您致电Dispatcher.AddTimer时,DispatcherTimer会通过调用内部Start方法向Dispatcher注册自己。

因为当你拨打Dispatcher.RemoveTimer时,它也会通过调用Stop取消注册,你就不会泄漏内存。

Timer使匿名方法在其Tick事件中保持活动状态,这也通过闭包使方法中的变量保持活动状态。

答案 1 :(得分:1)

.NET中内存泄漏的一个比较模糊的原因是事件处理程序。事件处理程序是对对象的引用,并将对象保留在范围内。完成事件处理程序后,需要删除它。如果事件处理程序只使用一次,它可以取消注册,但如果它被多次使用,则需要有一些其他对象知道它何时不再有用,并删除事件处理程序。