2010-06-02 61 views
1

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

所以我一直当有人点击我们的Silverlight应用程序图标的时候触发一个方法,如下所示:

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()开辟了一个包含公司信息并且调度计时器在所述时间段后自动关闭它。这一切工程...

但我不确定是因为派遣计时器是一个本地变量,在Logo_MouseLeftButtonUp方法完成后,有什么可以保持调度计时器引用和不可用GC收集在匿名方法被解雇之前?

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

只是觉得有些事情我应该更深入理解,因为我可以用事件等想象它可以很容易地创建一个像这样的东西泄漏。

希望这一切都有道理!

Andy。

+0

@johnny g - 全部完成! :)谢谢你的头!我有几个问题没有真正解决(比如emacs中的grep)。对于这些问题是否有最佳做法,还是在这些情况下可以接受不给予答案? TA! – Andy 2010-06-02 14:23:33

+0

不太确定,可能是SO礼仪常见问题,值得快速搜索。说实话,只要你沟通得好,并保持你的问题是最新的[例如“我相当肯定有一个更好的答案,因为......”]我相信社区会理解并做出适当的回应。好问题,好回应! :) – 2010-06-02 14:44:02

回答

9

调用Start时,DispatcherTimer通过调用内部Dispatcher.AddTimer方法向分派器注册自己。

由于当您拨打Stop时,您也可以通过拨打Dispatcher.RemoveTimer取消注册,因此您不会泄漏内存。

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

+0

啊,很酷,谢谢!猜猜我应该真的反映它而不是懒惰! :) – Andy 2010-06-02 14:11:18

+1

@安迪:你也应该接受你的问题的答案。 – 2010-06-02 14:12:20

+0

我打算这么做!大声笑,虽然很高兴给予反馈也! – Andy 2010-06-02 14:15:03

1

.NET中内存泄漏的一个比较晦涩的原因是事件处理程序。事件处理程序是对对象的引用,并将该对象保留在范围内。当你完成一个事件处理程序时,它需要被删除。如果事件处理程序仅使用一次,它可以注销自身,但是如果它不止一次使用,则需要有一些其他对象知道何时不再有用,并丢弃事件处理程序。