There seems to be some confusion of concepts.
Resource release is different from memory release. The Garbage Collector releases memory when it can and finds it necessary. It does not release resources.
What is to release resources?
When you have access to something "something" that has a link with the application at any given time this link needs to be finalized somehow. A typical example is the file on a disk. To access it, you open it by creating a link with the application. At some point this file needs to be closed by undoing this link. This needs to be done as soon as possible. You cannot wait for the Garbage Collector take action. You have no control when it will release the memory, GC tracings are not deterministic.
There are languages, usually without GC or with Counting, that the release of memory and release of the resource can be done in a synchronized way.
All classes that need this release must implement the interface IDisposable
, ie, need to create an implementation of the method Dispose()
which will end the linking of the resource with the application. It is therefore common for the implementation to call the method Close()
.
Someone might think, call the Close()
logo. Ok, you can do this. But you need a way to do this in a standardized way. You need to create a design pattern.
When the program creates an instance of a class that implements the Dispose()
, he must ensure that the method Dispose()
is called one way or another.
The most common is to use the statement using
. This way you create a scope, so when the instance goes out of scope, the method will be called "automatically" without you worrying. But you have to worry about creating the instance the right way, you have to create as using
. Some static analysis tools programs can help you by letting you know that you forgot to create the instance with the using
. Don’t be without the Resharper.
Because the Form
you don’t need this?
Of course you can call the Close()
on its own. What matters is Close()
be called. In this case the Close()
will call the Dispose()
if necessary.
An implicit closure of a form may call the Close()
for you. But it depends on how it was created.
The ShowDialog()
does not call the Close()
on its own. Then you should call. The ShowDialog()
closes the Form
in a different way (in a modal way), not providing the necessary untying. When it finishes running it is as if it has just been hidden away. Then you could call:
public void Show() {
using (var frm = new Form()) {
frm.ShowDialog();
}
}
If this is not possible, you will have to ensure, otherwise frm
is released when no longer required.
On the other hand if you call form1.Show()
or Application.Run(new Form1())
, the Close()
, and therefore the Dispose()
will be called by you. When you no longer want to show the form you should call the Hide()
, otherwise the Form
will be destroyed. View documentation.
Note that this destruction is related to the resource and not necessarily to the memory allocated to it. The memory will only be displaced by the GC.
Creating a class IDisposable
On the other hand if your concern is to implement a IDisposable
in your new class, it depends on whether you’re using a resource in it. Usually an external resource to the application, something that needs to be unlinked. Usually this is done at a lower abstraction level, where you will effectively manipulate the external resource more concretely.
The fact that you are using resources within your class does not require the implementation of IDisposable
. If you can guarantee the release of all resources within your own class, then it does not need to have the Dispose()
hers.
But if this can’t be guaranteed, then you need a Dispose()
implemented in it and probably within it all Dispose()
of the instances that need to be released should be called.
And if I forget to call Dispose()
?
Any attempt to access the resource can conflict (be denied, for example). But this will only occur until the first garbage collection. If there is no further reference to the instance, the GC will call the Finalize()
and this will call the Dispose()
, if necessary. Then the release of resources will occur at some point, even if it is at the close of the application.
This is valid if there is no catastrophic breakup. Of course, if . NET cannot complete correctly, none of this will happen. But then the operating system will probably resolve the situation by destroying all remaining links to an application that no longer exists, as well as the memory allocated to it. If the termination occurs by boot of the machine nor need to worry about anything, everything will be released for obvious reasons.
You should use Dispose when the object says in your documentation that it is not treated by Garbage Collector (and therefore should be disposed). An example is the class
System.Drawing.Bitmap
.– Mephy
I understand, but the answer seems a little vague to me. In this example I gave that I have a Form and a Label, wouldn’t I need a Dysplasia method? If it was a database handling class, it should use a Dispose that calls the connection Dispose?
– Latrova
The features of an object are automatically released by the GC after the object is no longer needed. But the resources automatically released are the so-called managed resources (or Managed Resources). Already the unmanaged resources (or Unmanaged Resources), as access to the disk, to the network, Handles, connections to the database... are not automatically released and require extra care, which can go through the implementation of the interface Idisposable. A hint is: if the object you consume is Disposable, try to secure the call to your method Dispose.
– Caffé