来自ContentControl中使用的Ioc的viewModel的可用内存

时间:2016-01-22 12:58:14

标签: c# wpf mvvm mvvm-light ioc-container

我目前正在使用ContentControl通过设置VM并使用如下默认数据模板来显示我的视图:

<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通过serviceLocator加载ViewModel:

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>())

这种方式似乎工作正常。

2 个答案:

答案 0 :(得分:1)

  

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

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

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

在实例可以进行垃圾回收之前,必须取消链接所有订阅。

  

如果我打电话给我,有时我的记忆被正确释放,但并非总是如此。

你在看应用程序的私有字节吗?对于操作系统报告一个完整的总数,如果操作系统没有压力,它不会消耗内存占用,允许应用程序呼吸可以这么说。专用字节将在完整分配的总数内上下移动。

所以你可能正在监视错误的值。

答案 1 :(得分: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>();
            });

如果有人有更好的方法来解决这种内存管理问题,我就完全开放了。