何时需要在图形上使用dispose()方法?

20

我正在学习在C#中绘制图形,我经常看到建议使用dispose(),但我不太明白它是什么。

  • 什么时候应该在代码绘制的图形上使用dispose()函数?
  • 如果我不使用它会发生什么?
  • 每次一个图形不可见时,例如在具有选项卡的GUI上并且用户切换到其他选项卡时,我需要调用它吗,然后在他们切换回来时重新绘制它吗?
  • 如果我在不应该调用它的时候调用它,会出现问题吗?
  • 蝙蝠侠能否逃脱小丑的魔掌?
4个回答

30
  • 什么时候应该在代码绘制的图形上使用dispose()?每当你完全使用任何实现了IDisposable接口的对象后,你都应该在它变得可以垃圾回收之前调用Dispose方法。正如其他人所指出的,最好使用using语句而不是直接调用Dispose
  • 如果我不这样做会发生什么?你的程序会稍微不那么高效,因为它将占用略多于必要的资源。这是不释放graphics的唯一缺点;然而,不释放其他类可能会导致错误(一个著名的例子是StreamWriter)。因此,通常最好释放任何实现了IDisposable接口的类。
  • 每次图形不可见(例如在具有选项卡的GUI上,用户切换到其他选项卡并重绘图形),我需要调用它吗? 不需要。当你完全使用完对象时才应该将其释放。
  • 如果我在不该调用它的时候调用它会破坏东西吗?会的。如果在完成对象之前调用Dispose,然后尝试使用已释放的对象,会抛出一个ObjectDisposedException异常。
  • 蝙蝠侠会摆脱小丑的邪恶掌控吗? 明天同一时间,请收听同一频道!

19
这需要再加一条规则:不要处理你没有创建的对象。 处理e.Graphics是一个令人讨厌的潜在错误。 - Hans Passant
3
对于 Graphics,需要注意的是,如果已经被释放,调用其 Draw... 方法将会抛出一个带有消息“参数无效”的 InvalidArgumentException 异常,而不是 ObjectDisposedException - reve_etrange

5
当您请求一个图形对象时,Windows会为您分配一部分内存。调用dispose将为您整理这段内存。如果您不调用dispose,则所有这些内存句柄将保持打开状态,最终您的系统将耗尽资源,变得更慢并最终停止运行(关闭程序可能会释放它们)。
因为您正在使用.NET,当您完成使用图形对象时,垃圾收集器最终会为您调用dispose。垃圾收集器的问题在于您永远不知道它何时清理对象,因此它可能会使这些资源保持打开状态的时间比必要的时间更长。
话虽如此,您应该永远不需要自己调用dispose。更好的方法是将对象放入using范围中:
using(Graphics g)
{
    // do something with the resource
}

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

3
在新手的讲解中,Dispose() 是用于在使用完未经托管的资源后清理资源的方法。
什么是未经托管的资源?它们是 CLR 不能为你管理的所有东西。它们包括文件句柄、数据库连接、网络套接字、GDI+ 笔等。你可以通过典型的 .NET 对象获得这些资源,但它会实现 IDisposable 接口,以允许你正确地清理资源。
为什么要清理资源?在你清理资源之前,其他程序部分就无法使用该资源。在这方面,你破坏了事物,因为你占用了资源。
为什么要自己做这个?你应该在不再需要资源时立即自己清理资源,而不是依赖垃圾回收器的自动幻术,因为在垃圾回收器对其进行处理之前,它可能需要很长的时间(好吧,未指定)。在对象被正确地处理之前,你无法重新使用底层资源,所以你的程序将无法可靠地运行。

0

Mitch Wheat - 对于任何实现IDisposable接口的对象,始终调用Dispose()方法。图形对象使用的GDI句柄是非托管的,在使用完毕后需要进行处理。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接