【问题标题】:Clear data from ObservableCollection从 ObservableCollection 清除数据
【发布时间】:2011-07-05 16:22:06
【问题描述】:

我有一个类可以存储图像及其文件名。我创建了此类的 ObservableCollection,并将其绑定到 WPF 列表框。 (它是一种图像查看器)

我加载了 50 meg 的数据(目前大约 10 张图像),然后我想从 observable 集合中删除一个、部分或全部图像并替换它们(这样内存占用不会变得太大而同时滚动浏览许多图像)。

首先,我实际上在 GUI 上有一个按钮来加载“接下来的 10 张图像”——它确实如此,但它使内存占用增加了一倍。我尝试从集合中调用 .Clear() 和 .ClearItems() 以及 .Remove() 和 .RemoveAt(n) 但内存没有减少。我是否误解了 ObservableCollection 的工作原理?

这是我的代码概要:

公共类 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 = 图像;

我希望我已经说清楚了......如果我应该添加任何内容,请告诉我!

编辑:现在我似乎已经通过覆盖 ObservableCollection 中的一个项目来解决问题,而不是尝试删除/清除它然后添加一个新项目。不过我还是不明白内存问题。

【问题讨论】:

  • 您会处理从收藏中删除的图像吗?
  • 我需要吗?在上面的 ObservableCollection 的 Load 中,我加载了图像 ImageData imgData = ImageData.Load(filename);,但我没有明确地处理它。它不应该持续存在,不是吗?

标签: c# .net wpf observablecollection


【解决方案1】:

可能是垃圾收集器尚未从内存中删除图像对象。原因可能是您的系统上有足够的可用内存,因此还没有必要删除对象。

当您加载接下来的 10 个图像和之后的 10 个图像时,内存消耗是否会继续上升?

您还应该考虑按照 Rakesh Gunijan 的建议处理图像。

【讨论】:

  • 它确实会不断为以下每组图像添加内存——不过我有 8Gb 的内存,所以你可能对垃圾收集器有所了解。
  • 您可以尝试为您的应用程序设置 MaxWorkingSet 以限制它可以分配多少内存。尝试使用 Process.GetCurrentProcess().MaxWorkingSet
  • 不,等等!这不会设置内存限制。查看此 SO 问题以了解强制执行限制的方法:stackoverflow.com/questions/4852062/…
  • 在阅读您的第二条评论之前,我尝试以 50mb 块的形式加载 2gb 的数据,但根本没有任何垃圾收集的证据。
【解决方案2】:

为什么不创建自己的视图模型类,如 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; } }

【讨论】:

  • 恕我直言,这对 OP 的记忆问题没有任何帮助。如果您认为它确实有帮助,请指出原因。
  • 恕我直言,您应该在视图中而不是在视图模型中创建 ImageData 对象。这将消除对象的处置,使应用程序更清洁。如果需要,在字符串 ImagePath 属性之间实现转换器。和 UI 图像对象。
  • 哇,我要花点时间才能弄清楚这里到底发生了什么!这对很多东西还是很陌生。感谢您的回复,我会调查一下。
  • @Zotty - 尽量保持应用程序简单。您的 ViewModel 不应加载 Image 对象。 View 负责加载 Image 对象。 ViewModel 应该只维护图像的路径(即字符串)。这将消除您面临的所有内存问题。或者用简单的语言来解读它,你的代码在 WPF 编程方面不适合。
  • 我假设“FIT”是指它不符合最佳实践?我想我理解您将图像加载到视图中的意思 - 我会看看我是否可以调整我的程序来做到这一点。它可能会解决我遇到的其他一些问题!我以前没有遇到过 View 和 ViewModel,我会去读一些。谢谢!
猜你喜欢
  • 2011-06-04
  • 2014-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-24
  • 2023-01-14
  • 1970-01-01
相关资源
最近更新 更多