在构建在SL4上的Caliburn.Micro应用程序中,我们遇到了(另一个)内存泄漏。
除去这个问题,这个问题似乎是由ItemsControl引起的,它将自定义DataTemplate绑定到实现INotifyPropertyChanged接口的对象的IEnumerable集合。
当更改源收集时(将另一个集合分配给ItemsControl的ItemsSource绑定到的ViewModel属性),原始收集和绑定DataTemplates中的实体不是垃圾收集。虽然NotifyPropertyChanged的事件处理似乎是通过WeakReference在内部完成的,但就像SL保留了对这些对象的另一个引用一样。因此,每次我们从服务器刷新数据时,内存消耗都会增加。
你知道如何解决这个问题吗?我真的不明白这种错误怎么会在SL4中发生!
一些实验表明,调用ItemsControl.Items.Clear()可能会有所帮助。任何提示,如何在每次更改ItemsSource时简单地调用它?我脑海中唯一想到的就是重写ItemsSourceProperty并在那里添加一个处理程序。
编辑:原来泄漏是在这种情况下发生的:
所发生的情况是,尽管实体被刷新,这可以从视图中看到,内存消耗正在上升。
如果没有绑定,那么刷新实体就不会占用更多内存(这可能是因为内存消耗水平最终会像GC一样返回)。
如果您清除了上下文,或者只是创建了一个新的上下文,那么内存最终也会被收集起来。
问题似乎与RIA服务有关。
如果您愿意,我可以提供一个简单的项目来显示问题。
更新:内存泄漏似乎是由INotifyDataErrorInfo引起的。读这里。
发布于 2010-08-23 14:27:57
更新:
Silverlight 4服务发布以修复内存泄漏:http://timheuer.com/blog/archive/2010/09/01/silverlight-service-release-september-2010-gdr1.aspx
Silverlight 4已经知道数据模板存在内存泄漏问题。它目前正在测试的方式有一个修复方法。
下面是我一直在关注的一条线索:
用户"heuertk“是一个Microsoft Developer....he,它解释了问题和修复的状态。
http://forums.silverlight.net/forums/t/171739.aspx
发布于 2010-09-13 12:32:14
据我理解,这个特定的问题是Silverlight 4本身的一个bug。但是,您说您遇到了另一个内存泄漏。你确定了那个是否与Caliburn.Micro有关吗?如果是的话,你在项目论坛上发布过吗?如果是CM的错误,我想试着修复它。谢谢。
发布于 2011-02-18 13:21:45
嘿,我在玩你的解决方案,我想出了一个很好的解决方案,基本上你把你的DataSrc类更改为下面,唯一的问题是如何在Ria实体上应用类似的东西。我已经在使用T4来调整代码生成(对于次要的事情),但我不确定是否可以在中间强制这样的东西。另外,我想问,你有没有向你的应用程序报告你的问题?额外的报告从不伤人:)
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;
}
}https://stackoverflow.com/questions/3529669
复制相似问题