C# 处理/删除控件后如何重新加载控件

C# 处理/删除控件后如何重新加载控件,c#,controls,dispose,reload,C#,Controls,Dispose,Reload,所以我想制作一个包含动态控件布局的程序,类似于网页。 我有一个特定的按钮,如果你点击它,它应该会处理所有可以看到的当前控件,并加载一个带有第二个InitializeComponent的全新控件集 第二个页面将包含一个“后退”按钮,该按钮用于处理第二组控件,并再次使用第一个InitializeComponent重新加载原始控件,这样我就有两个不同的可访问“页面” 但是,每次我通过按钮切换并再次调用InitializeComponent时,VRAM的使用量都会稳步增加,这可能是因为它不会真正使用di

所以我想制作一个包含动态控件布局的程序,类似于网页。 我有一个特定的按钮,如果你点击它,它应该会处理所有可以看到的当前控件,并加载一个带有第二个InitializeComponent的全新控件集

第二个页面将包含一个“后退”按钮,该按钮用于处理第二组控件,并再次使用第一个InitializeComponent重新加载原始控件,这样我就有两个不同的可访问“页面”

但是,每次我通过按钮切换并再次调用InitializeComponent时,VRAM的使用量都会稳步增加,这可能是因为它不会真正使用dispose“杀死”所有以前的资源

所以我想问,是否有一种方法可以重新加载已处理的初始化控件,而不必再次初始化它们

提前谢谢

编辑: 啊,没关系,我知道了

在切换到第2页时,我只使用Controls.Remove命令来删除当前的控件集,而不是.dispose。 如果我想回去,我现在可以简单地使用控件。添加命令以再次查看第一组控件,并且VRAM的使用不会增加


这在dispose中是不可能的,有人愿意解释一下吗?我是csharp的真正初学者,基本上是几天前开始的。

对任何一次性对象调用
Dispose
都会导致它释放(将引用设置为null)任何引用的一次性对象,并清理任何直接引用的非托管资源。在UI控件的情况下,将释放非托管的底层Win32 GUI对象。Dispose并不是释放内存以供重用,当对象没有被某个静态或堆栈(本地)引用(间接地)引用时,垃圾回收器会这样做。如果您保留对最后一页的引用(返回),则其
控件
集合中的控件仍将被引用并保持其活动状态

即使它们已从控件集合中删除,或者未被引用,由于UI控件往往存在一段时间,它们很可能已从第0代(频繁收集)移动到第1代甚至第2代(很少收集)。除非存在内存压力(您的系统没有太多的可用内存),否则收集它们可能需要很长时间

您可以通过使用WinDbg和SOS扩展查看特定于哪一代的对象(甚至列出该代中的所有对象)或强制完整收集来演示这一点


强制收集不是一个真正的解决方案,但可以证明这不是一个问题,当进程需要空闲内存时,它们将被释放,然后垃圾收集器将执行完整的收集。

实际上,您不应该自己调用Dispose()。通常,当您对表单等调用Close()时,框架将为您执行此操作。 显然,如果仍然存在对相应元素的引用,这并不总是导致删除相应元素。这就是为什么你在某种程度上仍然控制着你的位置


如果(出于某种原因)需要关闭()或删除()以及保留引用的元素,则应在执行任何其他操作之前执行element.IsDisposed检查。如果这是真的,您应该重新创建它,因为元素已经半死不活了。无亡灵术,请:-)

在删除事件处理程序之前,是否从控件中删除它们?这也许可以解释内存泄漏的原因。@Marco这是错误的方法——只要让它显示正在发生的事情,那么你就知道GC最终会处理它。仅显式收集以控制在重要的应用程序中何时进行收集。