Reputation: 16555
I have two code samples and I want to know what is the deifference between them and which is better to use as best practice and performance wise:
using (TestForm test = new TestForm())
{
test.ShowDialog();
}
and the other is:
TestForm test = null;
try
{
test = new TestForm();
test.ShowDialog();
}
catch(Exception ex)
{
}
finally
{
test = null;
}
Upvotes: 2
Views: 1598
Reputation: 32760
The IDisposable
pattern is a mechanism to timely free unmanaged and managed resources that an object may be consuming.
The typical way the pattern is implemented is as follows:
public void Dispose() //Implementes the IDisposable interface
{
this.Dispose(true);
GC.SupressFinalize(this); //All resources have been released, no need to run the finalizer. We make the GC's life a little easier;
}
protected void Dispose(bool disposing)
{
if (disposing)
{
//Relesase managed resources.
}
//Release unmanaged resources.
}
~MyDisposableObject() //finalizer
{
this.Dispose(false)
}
The thing to note here is that the release of resources through the Dispose
method is very similar to what you logically would expect to find in a finalizer. It is not done directly in the finalizer due to two main reasons:
the finalizer is not executed in a deterministic order. That is why we do not dispose managed resources from the finalizer (Dispose(false)
), as some or all the managed resources held by the object might have been finalized before the object itself. This is not true with unmanaged resources as, by definition, they will never be finalized by the GC
.
We do not know when the finalizer is run (it is up to the GC
).
The basic idea is that an object implementing IDisposable
is a sign for any consumer saying: "hey, I'm holding on to a certain amount of unmanaged and/or managed resources that will eventually be released when the GC
decides I'm no longer useful, but if you need those resources back in a timely way, call Dispose() and I'll be happy to oblige.".
On the other hand, setting a reference variable to null
is not freeing any resources at all. If the reference you have removed from the object was the only one to said object, then the object will eventually be collected by the GC
and managed and unmanaged resources will be freed (when, is anyones guess).
If there were more live references still pointing to the object, then the object would live one and no resources whatsoever would be freed.
Upvotes: -1
Reputation: 354576
Dispose()
is for freeing unmanaged resources. This may be done in a finalizer as well (which might call Dispose()
) but don't rely on it. If it isn't done, then you leak unmanaged resources.
Setting a reference to null
only means that a particular reference no longer points to that object. It can live on quite a while after that (or even indefinitely if you have another reference – well, if you have multiple reference to an object you Dispose()
d of, then it gets ugly, probably).
Generally, always call Dispose()
on IDiposable
s when you're done with them. It's easier if you wrap them into a using
statement:
using (var foo = new SomeDiposableObject()) {
// do something with foo
}
Upvotes: 4
Reputation: 7448
The IDisposable interface defines the Dispose method, as well as the possibility to use the "using" syntax. The dispose method of a class can be implemented to release resources, close database connections and any sort of finalizing and cleanup. Just setting the class instance to null won't execute any of the code defined in the dispose method. As a generic rule, if a class implements IDisposable, dispose should be called when you're finished with the class instance.
Upvotes: 7