Silverlight 4内存泄漏与ItemsControl
在基于Caliburn.Micro构建的SL4应用程序中,我们遇到了(另一个)内存泄漏 简单地说,问题似乎是由ItemsControl引起的,它将自定义DataTemplate绑定到实现INotifyPropertyChanged接口的IEnumerable对象集合 更改源集合时(将另一个集合分配给ItemsControl的ItemsSource绑定到的ViewModel属性),原始集合和绑定数据模板中的实体不会被垃圾收集。尽管NotifyPropertyChanged的事件处理似乎是通过WeakReference在内部完成的,但这就像SL保留了对这些对象的另一个引用一样。因此,每次我们从服务器刷新数据时,内存消耗都会增加 你知道如何解决这个问题吗? 我真的不明白SL4怎么会出现这种错误 一些实验表明,调用ItemsControl.Items.Clear()可能会有所帮助。有没有提示如何在每次更改ItemsSource时简单地调用它?我唯一想到的是重写ItemsSourceProperty并在那里添加一个处理程序 编辑: 结果表明,泄漏发生在这种情况下:Silverlight 4内存泄漏与ItemsControl,silverlight,memory-leaks,itemscontrol,Silverlight,Memory Leaks,Itemscontrol,在基于Caliburn.Micro构建的SL4应用程序中,我们遇到了(另一个)内存泄漏 简单地说,问题似乎是由ItemsControl引起的,它将自定义DataTemplate绑定到实现INotifyPropertyChanged接口的IEnumerable对象集合 更改源集合时(将另一个集合分配给ItemsControl的ItemsSource绑定到的ViewModel属性),原始集合和绑定数据模板中的实体不会被垃圾收集。尽管NotifyPropertyChanged的事件处理似乎是通过Wea
- 通过RIA服务上下文加载实体,并将它们的集合存储在viewmodel的属性中
- 将具有自定义数据模板的listview绑定到具有Entite集合的属性
- 通过RIA服务上下文刷新实体
更新:内存泄漏似乎是由INotifyDataErrorInfo引起的。阅读。更新: Silverlight 4服务版本修复内存泄漏: Silverlight 4已知数据模板存在内存泄漏问题。目前正在测试的方式有一个修正 以下是我一直遵循的一条线索: 用户“heuertk”是Microsoft Silverlight开发人员…他解释了问题和修复状态
据我所知,这个问题是Silverlight 4本身的一个bug。但是,您说您遇到了另一个内存泄漏。你确定那件事是否与Caliburn.Micro有关吗?如果是的话,你是否在项目论坛上发布过?如果故障在CM中,我想尝试修复它。谢谢。嘿,我对您的解决方案进行了一些研究,我提出了这个解决方案,效果很好,基本上您将DataSrc类更改为以下内容,唯一的问题是如何在Ria服务实体上应用类似的内容。我已经使用T4来调整代码生成(对于次要的事情),但我不确定是否可以在两者之间强制执行类似的操作。另外,我想问一下,您是否用示例应用程序报告了您的问题?额外的报告不会有什么坏处:)
公共类数据rc:INotifyDataErrorInfo
{
公共字符串名称{get;set;}
公共IEnumerable GetErrors(字符串propertyName)
{
屈服断裂;
}
public void InvokeEvent()
{
_OneEvent(这是新的DataErrorsChangedEventArgs(“名称”);
}
私人软弱者被改变(你软弱者被改变);;
公共事件事件处理程序错误更改
{
添加
{
_weakinkerrorChanged=新的weakinkerrorChanged(此);
_weaklinkorchanged.ErrorsChanged+=值;
}
删除{u weakinkerrorchanged.ErrorsChanged-=value;}
}
公共布尔错误
{
获取{return false;}
}
}
内部类的薄弱环节在TInstance:class处被更改
{
私有只读WeakReference\u weakInstance;
公共事件事件处理程序错误更改;
公共弱点已更改(TInstance实例)
{
if(实例==null)
{
抛出新的ArgumentNullException(“实例”);
}
_weakInstance=新的WeakReference(实例);
}
public void OneEvent(TSource源、DataErrorsChangedEventArgs事件args)
{
var target=_weakInstance.target作为TInstance;
如果(目标!=null)
{
if(ErrorsChanged!=null)
ErrorsChanged(目标、事件参数);
}
其他的
ErrorsChanged=null;
}
}
感谢您提醒我这个问题!你知道它是否发生在WPF?还不知道。但我将尝试为WPF和SL准备一个简单的演示来重现这个问题,我们拭目以待。你也有同样的问题吗?到目前为止,似乎连RIA都可能在某种程度上影响了这个问题……只是想确认一下:您在发布模式下测试这个问题,没有附加调试器,对吗?@Kent,这不重要。释放或调试模式,无论是否连接调试器,泄漏仍然存在。嗨,Rob。嗯,虽然这不是最新版本GDR1解决的众所周知的SL4错误,但它似乎与RIA服务有关。请参阅更新的问题。无论如何,非常感谢您的Caliburn Micro,它真的很棒!如果泄漏是由CM引起的,我会首先尝试自己修复,然后将修复方法发送给您:-)。嗨,Rob。我们最终跟踪了内存泄漏-它不是由C.Micro引起的,而是由SL本身引起的(INotifyDataErrorInfo)。我在博客上写过:
public class DataSrc :INotifyDataErrorInfo
{
public string Name { get; set; }
public IEnumerable GetErrors(string propertyName)
{
yield break;
}
public void InvokeEvent()
{
_weakLinkErrorChanged.OnEvent(this, new DataErrorsChangedEventArgs("Name"));
}
private WeakLinkErrorChanged<DataSrc, object> _weakLinkErrorChanged;
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged
{
add
{
_weakLinkErrorChanged=new WeakLinkErrorChanged<DataSrc, object>(this);
_weakLinkErrorChanged.ErrorsChanged += value;
}
remove { _weakLinkErrorChanged.ErrorsChanged -= value; }
}
public bool HasErrors
{
get { return false; }
}
}
internal class WeakLinkErrorChanged<TInstance, TSource> where TInstance : class
{
private readonly WeakReference _weakInstance;
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
public WeakLinkErrorChanged(TInstance instance)
{
if (instance == null)
{
throw new ArgumentNullException("instance");
}
_weakInstance = new WeakReference(instance);
}
public void OnEvent(TSource source, DataErrorsChangedEventArgs eventArgs)
{
var target = _weakInstance.Target as TInstance;
if (target != null)
{
if(ErrorsChanged!=null)
ErrorsChanged(target, eventArgs);
}
else
ErrorsChanged = null;
}
}