2016-01-22 31 views
3

我目前使用一个ContentControl中显示通过设置虚拟机,并使用这样的默认数据模板,我的看法:免费存储在ContentControl中使用

<UserControl.Resources> 
    <DataTemplate DataType="{x:Type vm:MyViewViewModel}"> 
     <views:MyView /> 
    </DataTemplate> 
</UserControl.Resources> 
<ContentControl Content="{Binding ContainerContent}"/> 

这里是我的ContainerContent:

public ViewModelBase ContainerContent 
{ 
    get 
    { 
     return _containerContent; 
    } 
    set 
    { 
     if (_containerContent != null) 
      _containerContent.Cleanup(); 

     _containerContent = value; 
     RaisePropertyChanged("ContainerContent"); 
    } 
} 

我目前使用SimpleIoc通过服务定位器来加载视图模型:

ContainerContent = ServiceLocator.Current.GetInstance<MyViewViewModel>(); 

这很好,并正确显示我的视图和viewModel分配给内容。

不幸的是,当我想从我的ContentControl中删除视图(和视图模型)时,由于ViewModel,View和SimpleIoc之间的发布顺序,我的内存仍然被使用。视图有一段时间引用它认为这是定时由于在容器上

我目前使用的方法,以除去内容RaisePropertyCHange后的结合):

public void QuitCurrentContainerViewModel<T>() where T : class 
     { 
      ContainerContent = null; 
      Task.Factory.StartNew(() => 
      { 
       if (/*!*/SimpleIoc.Default.ContainsCreated<T>()) 
       { 
        SimpleIoc.Default.Unregister<T>(); 
       } 
       DispatcherHelper.RunAsync(() => 
       { 
        MessageBox.Show("Do GC now"); 
        GC.Collect(); 

       }, DispatcherPriority.ApplicationIdle); 
      }); 
     } 

(使用调度和优先级是一个测试)

如果我称之为有时我的记忆被正确释放,但并非总是如此。

在每一种情况下,如果我从例如快捷方式强制GC.Collect,我的记忆是正确管理。

在我的情况下释放内存的好方法是什么?

谢谢!

编辑:我的坏,它正常工作与代码(在我QuitCurrentContainerViewModel方法我使用这个检查:

if (!SimpleIoc.Default.ContainsCreated<T>()) 

但我需要这样的:

if (SimpleIoc.Default.ContainsCreated<T>()) 

这样,它似乎工作正常

回答

0

这里的清洁没有无用的电话

public ViewModelBase ContainerContent 
      { 
       get 
       { 
        return _containerContent; 
       } 
       set 
       { 
        if (_containerContent != null) 
         _containerContent.Cleanup(); 

        _containerContent = value; 
        RaisePropertyChanged("ContainerContent"); 
       } 
      } 

      public void QuitCurrentContainerViewModel<T>() where T : class 
      { 
       ContainerContent = null; 
       Task.Factory.StartNew(() => 
       { 
        if (SimpleIoc.Default.ContainsCreated<T>()) 
        { 
         SimpleIoc.Default.Unregister<T>(); 
         GC.Collect(); 
        } 
//TODO: Do navigation or change of content  
       }); 
      } 

,在这里我的ContentContainer

Task.Factory.StartNew(() => 
      { 
       if (!SimpleIoc.Default.ContainsCreated<MyViewModel>()) 
        SimpleIoc.Default.Register<MyViewModel>(); 
       ContainerViewModel.ContainerContent = SimpleIoc.Default.GetInstance<MyViewModel>(); 
      }); 

加载我的代码,如果任何人有一个更好的办法来解决这个内存管理,我是完全开放的。

1

什么是在我的情况下释放内存的好方法?

对每个对象使用IDisposable模式,并在泛型类型说明符中要求它。这样,可以直接调用顶层实体,从而可以随后清理所有遵循界面的子引用。

请记住,具有订阅的实例(尽管实例未在代码中直接引用)将变为固定为,并且如果它们具有任何活动的订阅,它们将保持活动状态;保持垃圾收集器在海湾。

在垃圾收集实例之前,所有订阅都必须取消链接。

如果我打电话这有时我的记忆被正确地释放,但并不总是。

您是否正在查看应用程序的专用字节?对于操作系统报告的全部数据,如果操作系统没有受到压力,它不会消除内存占用量,允许应用程序呼吸。专用字节将在全部分配的总数内上下移动。

所以你可能会监测错误的值。

+0

感谢您的回复。我已经试图实现Idisposable没有成功。它认为dispose方法未被调用,因为视图在刷新之前“阻止”实例。 关于内存消耗,我使用私有字节的进程资源管理器性能视图。 – Tchoupi