C# .NET DataGridView控件占用了大量内存

C# .NET DataGridView控件占用了大量内存,c#,datagridview,C#,Datagridview,我正在我的应用程序中使用DataGridView控件,我遇到了一个奇怪的内存问题。我根本不使用数据绑定,只是手动填充。我在那里输入的数据一点也不多。我们讨论的是最多20行20列的数据 该控件的工作流程是,我有一个组合框,其中包含不同的“数据集”,在您选择它们时加载。因此,一个常见的使用场景是在comboBox中循环使用数据集,并看到它们在dataGrid中呈现。我看到的是,当人们循环浏览数据集时,应用程序内存使用量会立即从100MB跃升到1100MB,然后在GC启动时下降。但是,如果您快速循环浏

我正在我的应用程序中使用DataGridView控件,我遇到了一个奇怪的内存问题。我根本不使用数据绑定,只是手动填充。我在那里输入的数据一点也不多。我们讨论的是最多20行20列的数据

该控件的工作流程是,我有一个组合框,其中包含不同的“数据集”,在您选择它们时加载。因此,一个常见的使用场景是在comboBox中循环使用数据集,并看到它们在dataGrid中呈现。我看到的是,当人们循环浏览数据集时,应用程序内存使用量会立即从100MB跃升到1100MB,然后在GC启动时下降。但是,如果您快速循环浏览数据集(即比GC启动的速度快),您将耗尽内存,应用程序将死亡

调试后,我发现内存急剧增加的主要原因是数据网格中有一些图像类型的列。我使用它们显示一个16x16图标,指示该行的状态。这些图标存储在ImageList中,我只是在填充数据网格的行时将它们设置为该单元格的值。如果我取出图像并用简单的文本替换它们,我绝对看不到任何内存峰值

那么这里的交易是什么?为什么图像,微小的16x16,会让我的记忆中的控件变得疯狂

更多信息:

切换数据集时,我的逻辑是:

  • 清除所有网格行:dataGrid.rows.Clear()
  • 清除所有列:dataGrid.columns.Clear()
  • 将列添加到dataGrid控件:(大多数类型字符串和一些DataGridViewImageColumn)
  • 使用dataGrid.Rows.Add(object[]data)逐行添加我拥有的数据;(数据包括我需要用作图标的图像)

在第三段中,你说你的图标在图像列表中,但在你的逻辑步骤项目符号列表中,你说你正在将你需要的图像作为图标添加为对象数组。添加到dataGrid的ImageList是否有故障

DataGridView控件用于数据绑定。如果您根本不使用数据绑定,我建议您使用ListView控件

ListView已优化为显示图像。此外,实例化的内存比DataGridView要轻。另外,ListView控件允许您更改视图:

  • ListView.View=View.Details
  • ListView.View=View.LargeIcons
  • View=View.List
  • ListView.View=View.SmallIcons
  • ListView.View=View.Tile
  • 这些是您在Windows资源管理器中可能遇到的视图。您只需定义一个大图标ImageList,或一个小图标ImageList,或每个图标中的一个,具体取决于您允许用户查看的视图


    您也可以将网格线显示为DataGridView,只是为了提供相同的外观。

    顺便说一句,我决定用不同的方式来实现这一点。我已经求助于使用自定义绘画来绘制单元格中的图标。结果好多了。使用此解决方案,网格不再占用内存


    使用ListView是可能的,但不太实用,因为它只支持在第一列中放置图标。所以无论如何我都得做定制画

    我遇到了这个错误,它似乎是由引用ImageList中的图像引起的。为了解决这个问题,我在项目中创建了显示为内容的图像。然后,我使用Bitmap.FromImage(“images/test.png”)设置数据表中的图像值,这个奇怪的内存错误消失了。

    DataGridView在处理图像时似乎存在内存泄漏。在加载数据之前,将datagridview数据源设置为null,然后对数据源执行dispose(使用GC.Collect())。

    hmm。。。我真的没有想到这个选择。用ListView替换dataGrid应该很容易。我来试试看会发生什么。谢谢你的回答!DataGrid有一个Add方法,它以对象数组的形式获取整行。因此,对于该行中的列,我通过在imagelist中指定图标来添加所需的图标,如下所示:imagelist.Images[x]。所以这一切都来自于图像列表。我试图查看是否有方法将ImageList附加到DataGridView,但它没有这种功能。如果要添加列,则需要添加子项。