所以我想制作一个包含动态控件布局的程序,类似于网页。 我有一个按钮,如果你点击它,它应该处理所有可以看到的当前控件,并用第二个InitializeComponent加载一组完整的控件。
第二页将包含一个“后退”按钮,该按钮应该处理第二组控件,并再次使用第一个InitializeComponent重新加载原始控件,以便我有两种不同的可访问“页面”。
但是,每次我通过按钮切换并再次调用InitializeComponent时,VRAM的使用量将会稳步增加,可能是因为它并没有真正“杀死”以前所有的资源。
所以我想问一下是否有办法重新加载已经处理过的初始化控件而无需再次初始化它们。
提前致谢。
编辑: 啊,没关系,我明白了。
而不是.dispose我只是使用Controls.Remove命令在更改为第2页时删除当前控件集。 如果我想回去,我现在可以简单地使用Controls.Add命令再次查看第一组控件,并且VRAM使用率不会增加。
这是处理不可能的,有人在乎解释吗?我是csharp的真正初学者,基本上是几天前开始的。
答案 0 :(得分:1)
实际上你并不是真的应该自己调用Dispose()。通常,当您在Form上调用Close()时,框架将为您执行此操作。 显然,如果仍有对它的引用,这并不总是导致删除相应的元素。这就是你的控制仍然存在的原因。
如果您(出于某种原因)需要Close()或Remove()以及保留引用的元素,则应该执行element.IsDisposed检查,然后再执行其他操作。如果这是真的,你应该重新创建它,因为元素已经半死。没有死灵法术,请: - )
答案 1 :(得分:0)
在任何一次性对象上调用Dispose
应该使它释放(设置对null的引用)任何引用的一次性对象,并清理任何直接引用的非托管资源。在UI控件的情况下,处理将释放非托管的底层Win32 GUI对象。处理 not 关于释放内存以供重用,这是由垃圾收集器在没有通过某些静态或堆栈(本地)引用(间接)引用对象时完成的。如果您要保留对最后一页的引用(要返回),那么其Controls
集合中的控件仍将被引用并使它们保持活动状态。
即使将它们从控件集合中移除并且未被引用,因为UI控件倾向于存在一段时间,它们可能已经从第0代(经常收集)移动到第1代甚至2(很少收集) 。除非存在内存压力(系统没有太多可用内存),否则在收集它们之前可能需要很长时间。
您可以通过使用带有SOS扩展的WinDbg来查看这些生成特定对象(甚至列出该代中的所有对象),或强制完整集合来证明这一点。
强制集合不是一个真正的解决方案,但是会证明它不是问题,当进程需要空闲内存时它们将被释放,然后垃圾收集器将进行完整的收集。 / p>