简体   繁体   English

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

[英]When do I need to use dispose() on graphics?

I'm learning to draw stuff in C# and I keep seeing recommendations to use dispose(), but I don't quite understand what it does. 我正在学习用C#绘制东西,我一直看到使用dispose()的建议,但我不太明白它的用途。

  • When should I be using dispose() on a code-drawn graphic? 我什么时候应该在代码绘制的图形上使用dispose()?
  • What happens if I don't? 如果我不这样做会怎么样?
  • Do I need to call it every time a graphic is not visible, such as on a GUI that has tabs and the user switched to the other tab, and then redraw it when they switch back? 每次图形不可见时是否需要调用它,例如在具有选项卡的GUI上,用户切换到另一个选项卡,然后在切换回时重绘它?
  • Will I break things if I call it when I shouldn't? 如果我不打电话,我会打破它吗?
  • Will Batman escape the evil clutches of the Joker? 蝙蝠侠会逃脱小丑的邪恶魔掌吗?
  • When should I be using dispose() on a code-drawn graphic? 我什么时候应该在代码绘制的图形上使用dispose()? Whenever you are completely done with any object that implements IDisposable , you should call Dispose just before it becomes eligible for garbage collection. 每当你完成任何实现IDisposable对象时,你应该在它有资格进行垃圾收集之前调用Dispose As others have pointed out, it's best to use the using statement instead of calling Dispose directly. 正如其他人指出的那样,最好使用using语句而不是直接调用Dispose
  • What happens if I don't? 如果我不这样做会怎么样? Your program will be slightly less efficient because it will take up slightly more resources than necessary. 您的程序效率会稍低,因为它会占用比必要资源略多的资源。 This is the only drawback to not disposing graphics; 这是不处理图形的唯一缺点; however, not disposing other classes can actually cause errors (one famous example is StreamWriter ). 但是,不处理其他类实际上可能会导致错误(一个着名的例子是StreamWriter )。 For this reason, it's best to always dispose any class that implements IDisposable , as a general rule. 因此,作为一般规则,最好始终处置任何实现IDisposable类。
  • Do I need to call it every time a graphic is not visible, such as on a GUI that has tabs and the user switched to the other tab, and then redraw it when they switch back? 每次图形不可见时是否需要调用它,例如在具有选项卡的GUI上,用户切换到另一个选项卡,然后在切换回时重绘它? No. Objects should only be disposed when you are completely done with them. 不可以。对象只有在完成后才能进行处理。
  • Will I break things if I call it when I shouldn't? 如果我不打电话,我会打破它吗? Yes. 是。 If you call Dispose before you are done with the object, and then attempt to use the disposed object, you will get an ObjectDisposedException . 如果在完成对象之前调用Dispose ,然后尝试使用已处置的对象,则会得到ObjectDisposedException
  • Will Batman escape the evil clutches of the Joker? 蝙蝠侠会逃脱小丑的邪恶魔掌吗? Tune in tomorrow, same bat-time, same bat-channel! 明天收听,同样的蝙蝠时间,同样的蝙蝠频道!

When you ask for a graphical object, Windows will allocate a bit of memory for you. 当您要求图形对象时,Windows将为您分配一些内存。 Calling dispose will tidy up that memory for you. 调用dispose会为你整理那些记忆。 If you do not call dispose, all of these handles to memory wil remain open and eventually your system will run out of resources, become slower and eventually stop (closing the program may free them however). 如果你不调用dispose,所有这些内存句柄都将保持打开状态,最终你的系统将耗尽资源,变慢并最终停止(关闭程序可能会释放它们)。

Because you're using .NET, when you have finished using your graphics object, the garbage collector will eventually call dispose for you. 因为您使用的是.NET,所以当您使用完图形对象后,垃圾收集器最终会为您调用dispose。 The problem with the garbage collector is you never know when it will clean up the object, so it may leave these resources open for longer than necessary. 垃圾收集器的问题是你永远不知道什么时候它会清理对象,所以它可能会使这些资源打开的时间超过必要的时间。

This said, you should never have to call dispose yourself. 这就是说,你永远不应该自己打电话。 Far better will be to put your object in using scope: 更好的方法是将对象放在使用范围内:

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

Now when you leave this using scope, the object will be destroyed and dispose will be called automatically for you. 现在当你使用范围离开时,对象将被销毁,并且将自动为你调用dispose。 You should put all objects that have the dispose method defined inside a using scope. 您应该将具有dispose方法的所有对象放在using范围内。

In noob speak, Dispose() is about cleaning up after you're done using an unmanaged resource. 在noob说话中,Dispose()是关于在使用非托管资源完成后进行清理。

What's an unmanaged resource? 什么是非托管资源? It's all the stuff that CLR doesn't manage for you. 这是CLR无法为您管理的所有内容。 They're thing like file handles, database connections, network sockets, GDI+ pens, etc. You get access to those things through a typical .NET object, but it will implement IDisposable, to allow you to clean up properly. 它们就像文件句柄,数据库连接,网络套接字,GDI +笔等。您可以通过典型的.NET对象访问这些内容,但它将实现IDisposable,以便您正确清理。

Why clean up? 为什么清理? Until you've cleaned up after yourself, that resource isn't available by other parts of the program for use. 在您自己清理完之后,该程序的其他部分无法使用该资源。 In that respect, you're breaking things, because you're hogging a resource. 在这方面,你正在破坏事物,因为你正在占用资源。

Why do this yourself? 为什么这样做? You should do this yourself as soon as you stop needing the resource, rather than rely on the auto-magic of the garbage collector, because it could take a long (well, unspecified) amount of time before the garbage collector gets to it. 一旦停止需要资源,你应该自己这样做,而不是依赖垃圾收集器的自动魔法,因为在垃圾收集器到达它之前可能需要很长时间(很好,未指定)。 Until an object has been disposed of properly, you can't reuse the underlying resource, so you program will not function reliably. 在对象被正确处理之前,您无法重用底层资源,因此您的程序将无法可靠地运行。

Mitch Wheat says - Always call Dispose() on any object that implements IDisposable. Mitch Wheat - 总是在任何实现IDisposable的对象上调用Dispose()。 GDI handles used by graphics objects are unmanaged and require disposing when you are finished with them. 图形对象使用的GDI句柄是不受管理的,并且在完成它们时需要进行处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM