【问题标题】:Do I need to dispose non-static objects that are defined within a static object?我是否需要处置在静态对象中定义的非静态对象?
【发布时间】:2016-12-11 20:23:25
【问题描述】:

与 Visual Studio 中的默认 C# 模板一样,我将 Windows Form 定义为静态对象,如下所示:

public static FormMain formMain;

static void Main()
{
    formMain = new FormMain();
    Application.Run(formMain);
    formMain.Dispose();
}

如您所见,我在调用此静态表单之前为它分配了一个内存空间(使用new),并在表单关闭后释放了内存(使用Dispose)。

但是,在这个静态表单中,我定义了几个非静态对象(比如标签),如下所示:

public FormMain()
{
    // some code here
    Label myLabel1 = new Label();
    Label myLabel2 = new Label();
    Label myLabel3 = new Label();
    // some code here
}

现在,我有两个问题:

  1. 我是否也必须 Dispose 这些非静态对象,或者是否在调用 formMain.Dispose(); 行后立即释放它们(释放内存)?

  2. 如果我需要处理这些非静态对象,我应该在程序的哪个阶段使用Dispose(例如,在FormClosedFormClosing 事件中)?

注意:我尽量不使用 Visual Studio 中的表单设计工具,而是更喜欢逐行编写表单。

【问题讨论】:

  • Application.Run 已经在示例中处理了表单:“Form 类的 Dispose 方法将在 [the Application.Run] 方法的返回之前被调用。”
  • 我问的不是表单,而是表单中定义的非静态对象(myLabel1myLabel2 等)。
  • FormMain 应该释放它创建的成员变量。 FormMain 是否存储在静态变量中并不重要。
  • 一个表单将释放它的所有子控件。假设这些标签被添加到表单中,它们的处理就得到了处理。
  • 我的意思是调用表单的 Dispose 方法会导致它在其每个子控件上调用 Dispose。此外,由于表单和控件具有终结器,因此在终结期间任何非托管资源都将被清除。

标签: c# memory-management


【解决方案1】:

与 Visual Studio 中的默认 C# 模板一样,我将 Windows 窗体定义为静态对象,如下所示:

不确定为什么要将应用程序主窗口表单存储为公共静态字段。您在考虑什么特定场景?

如你所见,在调用之前我已经为这个静态表单分配了一个内存空间(使用new)......

这不是 C++。在 C# 中调用 new 是强制性的,在引用类型方面它不是一个选项。

并在表单关闭后释放内存(使用Dispose)。

调用Dispose 根本不会释放托管内存。我建议您阅读IDisposable 模式和托管内存模型,您似乎在这里误解了很多。

我是否也必须处置这些非静态对象,或者它们是否在 formMain.Dispose(); 之后立即处置(释放内存);行被调用?

静态或非静态无关紧要,您应该处理所有一次性物品。阅读this了解更多信息

如果我需要处置这些非静态对象,我应该在程序的哪个阶段使用 Dispose(例如,在 FormClosed 或 FormClosing 事件中)?

您应该按照IDisposable 模式的准则进行处理。

【讨论】:

  • 关于有问题的程序;我有 (1) 一些在方法中定义的标签(例如,FormMain())和 (2) 在 @ 的主体中定义的一些其他标签987654329@ 类(我在主体和public 中定义它们,因为我使用它们与其他形式进行交互)。到目前为止,我推断,对于使用 in 方法定义的标签(具有范围),我不需要处理它们。另一方面,对于在表单主体中定义为 public 的标签,我需要在关闭表单之前处理它们(在 FormClosing 事件中)。我说的对吗?
  • @ssd 没有,没有,也没有。您应该根据IDisposable 模式处理对象,忘记事件。此外,您在方法中创建的标签(如果您希望它们有任何用途)可能会添加到表单的 Controls 集合中,因此即使本地名称超出范围,对象仍然可以访问。我的建议:忘记表单、控件和事件。您需要先了解基础知识。阅读托管内存模型,了解它,然后在此基础上进行构建。你似乎在学会爬行之前就已经在尝试花样滑冰了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多