我有一个类存储图像及其文件名。我已经创建了这个类的ObservableCollection,并将其绑定到WPF列表框。 (这是各种图像查看器)
我加载了50兆的数据(目前大约有10个图像),然后我想从可观察集合中删除一个,部分或全部图像并替换它们(这样内存占用空间不会太大而滚动浏览许多图片。)
首先,我实际上在GUI上有一个按钮来加载“接下来的10个图像” - 它确实如此,但它会使内存占用量增加一倍。我试过从集合中调用.Clear()和.ClearItems(),以及.Remove()和.RemoveAt(n),但内存不会减少。我是否误解了ObservableCollection的工作原理?
以下是我的代码概要:
public class ImageDataList : ObservableCollection
{
public static ImageDataList Load(string path,int startVal, ImageDataList images)
{
// Load 10 images from defined start position
if (startVal<0)
startVal=0;
int endVal = startVal + 10;
if (endVal > Directory.GetFiles(path).Length)
endVal = Directory.GetFiles(path).Length;
// Attempt to clear all data from collection
images.ClearItems();
images.Clear();
while (images.Count>1)
{
images.RemoveAt(0);
}
for (int i = startVal; i < endVal; i++)
{
string filename = Directory.GetFiles(path)[i];
if (filename.Contains(".tif"))
{
ImageData imgData = ImageData.Load(filename);
images.Add(imgData);
}
}
return images;
}
}
加载图像后,通过以下方式传递给GUI:
listBox.DataContext = images;
我希望我一直很清楚......如果我想添加任何东西,请告诉我!
编辑:现在我似乎通过覆盖ObservableCollection中的项目来解决问题,而不是尝试删除/清除它然后添加一个新项目。我仍然不明白记忆问题。
答案 0 :(得分:3)
垃圾收集器可能尚未从内存中删除图像对象。原因可能是您的系统上有足够的可用内存,因此无需删除对象。
加载接下来的10张图像时,内存消耗是否继续上升?之后的10张图像是否继续上升?
你也应该考虑按照Rakesh Gunijan的建议处理图像。
答案 1 :(得分:1)
为什么不创建自己的视图模型类,如ImageDataViewModel并创建它的可观察集合,而不是继承自ObservableCollection。
public class ImageDataViewModel : INotifyPropertyChanged, IDisposable
{
private string _id;
private string _imagePath;
public string Id
{
get
{
return _id;
}
set
{
_id = value;
OnPropertyChanged("Id");
}
}
public string ImagePath
{
get
{
return _imagePath;
}
set
{
_imagePath = value;
OnPropertyChanged("ImagePath");
}
}
private void OnPropertyChanged(string propertyName)
{
if(PropertyChanged!=null)
{
PropertyChanged(this,new PropertyChangedEventArgs(propertyName));
}
}
public void Dispose()
{
//Do dispose of resources.
}
public event PropertyChangedEventHandler PropertyChanged;
}
public class YourViewModel : INotifyPropertyChanged, IDisposable
{
private ObservableCollection _images;
public ObservableCollection Images
{
get
{
return _images;
}
set
{
_images = value;
OnPropertyChanged("Images");
}
}
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void Dispose()
{
Images = null;
}
}