从 ContentControl 中使用的 Ioc 的 viewModel 中释放内存
本文关键字:内存 viewModel 释放 Ioc ContentControl | 更新日期: 2023-09-27 18:31:30
我目前正在使用 ContentControl 通过设置 VM 并使用默认数据模板来显示我的视图,如下所示:
<UserControl.Resources>
<DataTemplate DataType="{x:Type vm:MyViewViewModel}">
<views:MyView />
</DataTemplate>
</UserControl.Resources>
<ContentControl Content="{Binding 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>();
这很好用,可以相应地显示我的视图,并且视图模型已分配给内容。
不幸的是,当我想从我的 ContentControl 中删除视图(和视图模型)时,由于 ViewModel、View 和 SimpleIoc 之间的发布顺序,我的内存仍在使用。
我目前使用一种方法来删除内容:
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。例如,从快捷方式收集,我的内存得到了正确管理。
在我的情况下释放内存的好方法是什么?
谢谢!
编辑:我的错,它与该代码一起工作(在我的QuitCurrentContainerViewModel方法中,我使用此检查:
if (!SimpleIoc.Default.ContainsCreated<T>())
但我需要这个:
if (SimpleIoc.Default.ContainsCreated<T>())
这样它似乎工作正常。
在我的情况下释放内存的好方法是什么?
对每个对象使用 IDisposable 模式,并在泛型类型说明符中要求它。这样,可以直接调用顶级实体,该实体随后可以清理其所有遵循接口的子引用。
请记住,具有订阅的实例(尽管该实例未在代码中直接引用)将变为固定状态,如果它们有任何处于活动状态的订阅,则会保持活动状态;阻止垃圾回收器。
必须先取消链接所有订阅,然后才能对实例进行垃圾回收。
如果我有时调用这个,我的记忆会被正确释放,但并非总是如此。
您是否正在查看应用程序的私有字节?对于操作系统报告完整的总数,如果操作系统没有压力,它不会占用内存,让应用程序可以呼吸。专用字节将在完全分配的总数内上下移动。
因此,您可能正在监视错误的值。
的代码在没有无用调用的情况下清理
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
});
}
在这里我加载了内容容器
Task.Factory.StartNew(() =>
{
if (!SimpleIoc.Default.ContainsCreated<MyViewModel>())
SimpleIoc.Default.Register<MyViewModel>();
ContainerViewModel.ContainerContent = SimpleIoc.Default.GetInstance<MyViewModel>();
});
如果有人有更好的方法来解决这个内存管理,我完全开放。