我什么时候需要在图形上使用dispose()?

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

  • 我什么时候应该在代码绘制的图形上使用dispose()?
  • 如果我不这样做会怎么样?
  • 每次图形不可见时是否需要调用它,例如在具有选项卡且用户切换到其他选项卡的GUI上,然后在切换回时重绘它?
  • 如果我不打电话,我会打破它吗?
  • 蝙蝠侠会逃脱小丑的邪恶魔掌吗?

  • 我什么时候应该在代码绘制的图形上使用dispose()? 每当您完成任何实现IDisposable对象时,您应该在它有资格进行垃圾回收之前调用Dispose 。 正如其他人指出的那样,最好使用using语句而不是直接调用Dispose
  • 如果我不这样做会怎么样? 您的程序效率会稍低,因为它会占用比必要资源略多的资源。 这是不处理图形的唯一缺点; 但是,不处理其他类实际上可能会导致错误(一个着名的例子是StreamWriter )。 因此,作为一般规则,最好始终处理任何实现IDisposable类。
  • 每次图形不可见时是否需要调用它,例如在具有选项卡且用户切换到其他选项卡的GUI上,然后在切换回时重绘它? 不可以。对象只有在完成后才能进行处理。
  • 如果我不打电话,我会打破它吗? 是。 如果在完成对象之前调用Dispose ,然后尝试使用已处置的对象,则会得到ObjectDisposedException
  • 蝙蝠侠会逃脱小丑的邪恶魔掌吗? 明天收音,同样的蝙蝠时间,同样的蝙蝠频道!

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

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

这就是说,你永远不应该自己打电话。 更好的方法是将对象放在使用范围内:

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

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

在noob说话中,Dispose()是关于在使用非托管资源完成后清理的。

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

为什么清理? 在您自己清理完之后,该程序的其他部分无法使用该资源。 在这方面,你正在破坏事物,因为你正在占用资源。

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

Mitch Wheat 说 – 总是在任何实现IDisposable的对象上调用Dispose()。 图形对象使用的GDI句柄是不受管理的,并且在完成它们时需要进行处理。