Очистить данные из ObservableCollection - PullRequest
1 голос
/ 28 февраля 2011

У меня есть класс, который хранит изображение вместе с именем файла.Я создал ObservableCollection этого класса и привязал его к списку WPF.(Это своего рода просмотрщик изображений)

Я загружаю данные объемом 50 мегабайт (в настоящее время около 10 изображений), затем я хочу удалить одно, несколько или все изображения из наблюдаемой коллекции и заменить их (так чточто объем памяти не становится слишком большим при прокрутке многих изображений).

Для начала, у меня на самом деле есть кнопка в графическом интерфейсе для загрузки «следующих 10 изображений» - что он и делает,но это удваивает объем памяти.Я пытался вызвать .Clear () и .ClearItems () из коллекции, а также .Remove () и .RemoveAt (n), но память не уменьшается.Я неправильно понимаю, как работает ObservableCollection?

Вот краткий обзор моего кода:

public class ImageDataList : ObservableCollection
            {</p>

<code>            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;
            }
        }
</code>

После загрузки изображений он передается в графический интерфейс через:

listBox.DataContext = images;

Надеюсь, я все понял ... дайте мне знать, если я что-нибудь добавлю!

Редактировать: Пока я, кажетсярешили проблему, переписав элемент в ObservableCollection, вместо того, чтобы пытаться удалить / очистить его, а затем добавить новый.Я все еще не понимаю проблемы с памятью.

Ответы [ 2 ]

3 голосов
/ 28 февраля 2011

Возможно, сборщик мусора еще не удалил объекты изображения из памяти.Причиной может быть то, что в вашей системе достаточно памяти, поэтому нет необходимости удалять объекты.

Продолжает ли увеличиваться потребление памяти при загрузке следующих 10 изображений и следующих 10 после этого?

Вам также следует рассмотреть возможность утилизации изображений, как рекомендует Ракеш Гуниджан.

1 голос
/ 28 февраля 2011

Почему бы вам не создать свой собственный класс модели представления, такой как ImageDataViewModel, и создать его из наблюдаемой коллекции вместо того, чтобы наследовать от ObservableCollection.

<Code>
 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;
        }
    }

</Code>
...