Silverlight:Memory Leak处理

           Silverlight开发中可能会遇到各种内存泄露的情形,由于CLR本身给我们提供了垃圾回收功能,所以在一般的情况下,我们也可能不是太重视内存是否得到有效的释放,

           本文试图还原自己遇到一个场景,给各位做Silverlight的朋友们一个参考.

           那么我处理的情形是在Silverlight自带的导航框架中遇到的,我将ViewModel绑定到对应的View中,唯一的区别是我的Viewmodel中包含了一个DispatcherTimer.

           看我的Viewmodel的代码:

       public class AboutViewModel : ViewModelBase,IDisposable
   {
   public static Lazy<DispatcherTimer> _dispatcher;
   private string _currentDateTime;
   public AboutViewModel()
   {
       _dispatcher = new Lazy<DispatcherTimer>();
       _dispatcher.Value.Interval = TimeSpan.FromSeconds(1);
       _dispatcher.Value.Tick += _dispatcher_Tick;
       _dispatcher.Value.Start();
   }
 
   public string CurrentDateTime
   {
       get { return _currentDateTime; }
       set { _currentDateTime = value;
        Notify(()=>CurrentDateTime); 
       }
   }
 
    void _dispatcher_Tick(object sender, EventArgs e)
   {
       _dispatcher.Value.Tick -= _dispatcher_Tick;
       CurrentDateTime = DateTime.Now.ToLongTimeString();
       _dispatcher.Value.Tick += _dispatcher_Tick;
   }
 
   public void Dispose()
   {
       _dispatcher.Value.Stop();
       _dispatcher = null;
   }
          我将CurrentDateTime绑定到View上:
   <TextBlock x:Name="ContentText" Style="{StaticResource ContentTextStyle}" 
                        Text="{Binding CurrentDateTime,Mode=TwoWay}"/>

image

       这个典型的MVVM模式的应用,不过问题也随之出现了:

       当你切换到home页面时,理论上about页面已经被销毁,但是如果你此时在AboutViewModel中的_dispatcher_Tick处断点时,你会发现它仍然在执行Tick事件.你尝试在Dispose方法断点时,你会发现

      切换页面时,也确实没有调用到这个方法.

       需要强调的一点是,上面这个例子并不是因为由于MVVM模式才导致内存泄露,而是事件强引用本身没有得到释放.

       那么我最终处理的方式是Page的Unload事件中调用Dispose方法.

     public About()
   {
    InitializeComponent();
    DataContext = new AboutViewModel();
    this.Unloaded += new RoutedEventHandler(About_Unloaded);
   }
 
   void About_Unloaded(object sender, RoutedEventArgs e)
   {
  (DataContext as AboutViewModel).Dispose();
   }

    关于Silverlight内存泄露的文章,网上也说了很多了,本例子希望给遇到的朋友一个简单的处理方式,如果对上面的例子有更好的方式,希望能提出来分享.

 

 

 

    代码下载:内存泄露示例

posted @ 2012-09-21 14:32  ringgo  阅读(1791)  评论(3编辑  收藏  举报