【问题标题】:When do I need to use dispose() on graphics?什么时候需要在图形上使用 dispose()?
【发布时间】:2010-07-03 10:27:13
【问题描述】:

我正在学习用 C# 绘制东西,我不断看到使用 dispose() 的建议,但我不太明白它的作用。

  • 什么时候应该使用 dispose() 代码绘制的图形?
  • 如果我 不?
  • 我需要每次调用它吗 图形不可见的时间,例如 就像在具有选项卡和 用户切换到另一个选项卡,并且 然后在他们切换回来时重新绘制它?
  • 如果我不应该调用它,我会破坏事情吗?
  • 蝙蝠侠会逃脱小丑的魔爪吗?

【问题讨论】:

    标签: c# user-interface graphics dispose


    【解决方案1】:
    • 我什么时候应该在代码绘制的图形上使用 dispose()? 每当你完全处理完任何实现 IDisposable 的对象时,你应该在它有资格进行垃圾回收之前调用 Dispose .正如其他人所指出的,最好使用using 语句,而不是直接调用Dispose
    • 如果我不这样做会怎样?你的程序效率会稍低一些,因为它会占用比需要更多的资源。这是不释放图形的唯一缺点;然而,不释放其他类实际上会导致错误(一个著名的例子是StreamWriter)。因此,作为一般规则,最好始终处置任何实现 IDisposable 的类。
    • 我是否需要在每次图形不可见时调用它,例如在具有选项卡的 GUI 上并且用户切换到另一个选项卡,然后在切换回来时重新绘制它? 不需要。对象仅在您完全处理完它们后才应处置。
    • 如果我不应该调用它,我会破坏它吗? 是的。如果您在完成对象之前调用Dispose,然后尝试使用已释放的对象,您将获得ObjectDisposedException
    • 蝙蝠侠能逃脱小丑的魔爪吗? 明天收听,同样的蝙蝠时间,同样的蝙蝠频道!

    【讨论】:

    • 这需要另外一条规则:不要处置你没有创建的对象。处理 e.Graphics 是一个令人讨厌的潜在错误。
    • 只是对Graphics 的注释,如果它已被处理,则调用其Draw... 方法将给出InvalidArgumentException 并带有消息“参数无效” - 而不是ObjectDisposedException
    【解决方案2】:

    当您请求图形对象时,Windows 会为您分配一点内存。调用 dispose 将为您整理该内存。如果您不调用 dispose,所有这些内存句柄将保持打开状态,最终您的系统将耗尽资源、变慢并最终停止(但关闭程序可能会释放它们)。

    因为您使用的是 .NET,所以当您使用完图形对象后,垃圾收集器最终会为您调用 dispose。垃圾收集器的问题是您永远不知道它何时会清理对象,因此它可能会使这些资源保持打开状态的时间超过必要的时间。

    这就是说,您永远不必自己调用 dispose。将你的对象放在使用范围内会更好:

    using(Graphics g)
    {
        // do something with the resource
    }
    

    现在,当您离开 this using 范围时,该对象将被销毁,并且会自动为您调用 dispose。您应该将所有定义了 dispose 方法的对象放在 using 范围内。

    【讨论】:

      【解决方案3】:

      用菜鸟的话说,Dispose() 是关于在您使用完非托管资源后进行清理。

      什么是非托管资源?这是 CLR 无法为您管理的所有内容。它们类似于文件句柄、数据库连接、网络套接字、GDI+ 笔等。您可以通过典型的 .NET 对象访问这些东西,但它将实现 IDisposable,以便您正确清理。

      为什么要清理? 在您自己清理之前,该资源不能被程序的其他部分使用。在这方面,您正在破坏事物,因为您占用了资源。

      为什么要自己做?你应该在不再需要资源后立即自己做,而不是依赖垃圾收集器的自动魔法,因为这可能需要很长时间(嗯,未指定)垃圾收集器到达它之前的时间量。在正确处理对象之前,您无法重用底层资源,因此您的程序将无法可靠地运行。

      【讨论】:

        【解决方案4】:

        Mitch Wheat says - 始终在任何实现 IDisposable 的对象上调用 Dispose()。图形对象使用的 GDI 句柄是非托管的,需要在使用完它们后进行处理。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-06-12
          • 1970-01-01
          • 1970-01-01
          • 2012-09-16
          • 2011-08-11
          • 1970-01-01
          • 2017-06-17
          相关资源
          最近更新 更多