内存泄漏和局部变量
本文关键字:局部变量 泄漏 内存 | 更新日期: 2023-09-27 18:19:00
我有以下方法(在prism的RegionAdapter中):
protected override void Adapt(IRegion region, DocumentPane regionTarget)
{
region.Views.CollectionChanged += delegate(object sender, NotifyCollectionChangedEventArgs e)
{
OnViewsCollectionChanged(sender, e, region, regionTarget);
};
}
我的问题是,通过这种方式订阅事件,我有内存泄漏。但是region和regionTarget参数是Adapt的局部变量。
我试着查找这个,看看是否有人以不同的方式处理场景,但MSDN和mvp都使用这种泄漏的方法…
我应该如何处理它,以便以后可以取消订阅该事件?
编辑:
上面的代码只是一个例子,我认为它清楚地说明了问题。
泄漏内存的实际代码如下:
private void OnViewsCollectionChanged(object sender,
NotifyCollectionChangedEventArgs e, IRegion region,
DocumentPane regionTarget)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
//Add content panes for each associated view.
foreach (object item in e.NewItems)
{
UIElement view = item as UIElement;
if (view != null)
{
DockableContent newContentPane = new DockableContent();
newContentPane.IsCloseable = true;
newContentPane.HideOnClose = false;
ScrollViewer sViewer = new ScrollViewer()
{
Content = item,
HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
VerticalScrollBarVisibility = ScrollBarVisibility.Auto
};
newContentPane.Content = sViewer;
//When contentPane is closed remove the associated region
// (MEMORY LEAK)
newContentPane.Closed += (contentPaneSender, args) =>
{
DockableContent docker =
contentPaneSender as DockableContent;
ScrollViewer scroller = docker.Content as ScrollViewer;
region.Remove(scroller.Content);
IDisposable dispView = scroller.Content as IDisposable;
if (dispView != null) dispView.Dispose();
scroller.Content = null;
};
regionTarget.Items.Add(newContentPane);
newContentPane.Activate();
}
}
}
}
谢谢,
巴布。
使用具体方法代替匿名方法。例:
private Region _region;
DocumentPane _regionTarget
protected override void Adapt(IRegion region, DocumentPane regionTarget)
{
_region = region;
_regionTarget = regionTarget;
region.Views.CollectionChanged += OnCollectionChanged;
}
private void OnCollectionChanged (object sender, NotifyCollectionChangedEventArgs e)
{
OnViewsCollectionChanged(sender, e, _region, _regionTarget);
}
...
private void Unsubscribe()
{
_region.Views.CollectionChanged -= OnCollectionChanged;
}