Reputation: 817
I've got a class that stores an image along with it's filename. I've created an ObservableCollection of this class, and bound that to a WPF listbox. (It's an image viewer of sorts)
I load 50 meg worth of data (currently about 10 images), then I want to remove one, some or all of the images from the observable collection and replace them (so that the memory footprint doesn't get too big while scrolling through many images).
For a start, I've actually got a button on the GUI to load the "next 10 images" - which it does, but it doubles the memory footprint. I've tried calling .Clear() and .ClearItems() from the collection, and also .Remove() and .RemoveAt(n) but the memory doesn't decrease. Am I mistunderstanding how ObservableCollection works?
Here's a synopsis of my code:
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;
}
}
After loading the images, it's passed to the GUI via:
listBox.DataContext = images;
I hope I've been clear... let me know if I should add anything!
Edit: For now I seem to have solved the problem by overwriting an item in the ObservableCollection, rather than trying to remove/clear it then add a new one. I still don't understand the memory problem though.
Upvotes: 2
Views: 11217
Reputation: 1288
Why dont you create your own view model class like ImageDataViewModel and create observable collection of it instead of inheriting from 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;
}
}
Upvotes: 1
Reputation: 36300
It may be that the garbage collector hasn't deleted the image objects from memory yet. The reason may be that you have enough memory available on your system so there is no need to delete the objects yet.
Does the memory consumption continue to rise when you load the next 10 images and the next 10 after that?
You should also consider disposing the images as Rakesh Gunijan suggests.
Upvotes: 3