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

2019-02-05 20:40发布

问题:

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.

  • When should I be using dispose() on a code-drawn graphic?
  • 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?
  • Will I break things if I call it when I shouldn't?
  • Will Batman escape the evil clutches of the Joker?

回答1:

  • When should I be using dispose() on a code-drawn graphic? Whenever you are completely done with any object that implements IDisposable, you should call Dispose just before it becomes eligible for garbage collection. As others have pointed out, it's best to use the using statement instead of calling Dispose directly.
  • 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). For this reason, it's best to always dispose any class that implements IDisposable, as a general rule.
  • 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? 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.
  • Will Batman escape the evil clutches of the Joker? Tune in tomorrow, same bat-time, same bat-channel!


回答2:

When you ask for a graphical object, Windows will allocate a bit of memory for you. Calling dispose will tidy up that memory for you. 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).

Because you're using .NET, when you have finished using your graphics object, the garbage collector will eventually call dispose for you. 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. You should put all objects that have the dispose method defined inside a using scope.



回答3:

In noob speak, Dispose() is about cleaning up after you're done using an unmanaged resource.

What's an unmanaged resource? It's all the stuff that CLR doesn't manage for you. 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.

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.



回答4:

Mitch Wheat says - Always call Dispose() on any object that implements IDisposable. GDI handles used by graphics objects are unmanaged and require disposing when you are finished with them.