fra*_*fra 4 .net c# memory-leaks mef .net-4.0
我们在MVVM应用程序中使用MEF(.NET 4,目前不能使用4.5).一切都很好,直到我们需要动态创建模型,例如表格的可编辑行.我不想遇到内存泄漏,我发现这篇文章http://pglazkov.blogspot.ch/2011/04/mvvm-with-mef-viewmodelfactory.html我发现了一个我想要了解的意外行为.这是添加到Shell.Items可观察集合的Item:
[PartCreationPolicy(CreationPolicy.NonShared)]
[Export]
public class Item : INotifyPropertyChanged, IDisposable
{
[Import]
private Lazy<Shell> shell;
/// <summary>
/// Initializes a new instance of the <see cref="Item"/> class.
/// </summary>
public Item()
{
this.Time = DateTime.Now;
}
~Item()
{
this.Dispose(false);
}
public event PropertyChangedEventHandler PropertyChanged;
public Shell Shell
{
get
{
return this.shell.Value;
}
}
public DateTime Time { get; private set; }
public void Initialize()
{
this.Shell.ItemsCount++;
}
public void Dispose()
{
this.Dispose(true);
}
private void Dispose(bool disposing)
{
if (disposing)
{
this.Shell.ItemsCount--;
}
}
[..]
}
Run Code Online (Sandbox Code Playgroud)
这是工厂:
[PartCreationPolicy(CreationPolicy.Shared)]
[Export]
public class ChildContainerItemFactory : ItemFactory
{
public override Item Create()
{
var container = ServiceLocator.Current.GetInstance<CompositionContainer>();
using (var childContainer = CreateTemporaryDisposableContainer(container))
{
var item = childContainer.GetExportedValue<Item>();
item.Initialize();
return item;
}
}
[..]
}
Run Code Online (Sandbox Code Playgroud)
如果我使用此代码,则Item与子容器一起处理.如果我将其更改为:
public override Item Create()
{
var container = ServiceLocator.Current.GetInstance<CompositionContainer>();
using (var childContainer = CreateTemporaryDisposableContainer(container))
{
var item = new Item();
childContainer.SatisfyImportsOnce(item);
item.Initialize();
return item;
}
}
Run Code Online (Sandbox Code Playgroud)
该物品不再与容器一起处理.我想了解使用GetExportedValue方法是否危险(我在应用程序的其他部分使用该方法),这是避免内存泄漏的最佳实践,对于寿命较短的视图模型.
任何帮助赞赏
据我所知(通过实验和查看MEF的源代码):
现在,GetExportedValue和SatisfyImports之间的区别并不相同.GetExportedValue返回向容器注册的所有导出部件.这包括容器创建的部件(1.中提到的导出的目录部件)以及使用CompositionContainer.ComposeParts注册的部件.SatisfyImports将注入任何可用的导入,但不会将该对象注册为导出,即使其类被标记为导出类型(请参阅1.).此外,SatisfyImports将禁用重组,但这不是主题.
MEF关于CodePlex的文档提供了有关Parts Lifetime的有价值信息.
| 归档时间: |
|
| 查看次数: |
3229 次 |
| 最近记录: |