When is destructor called for C# classes in ASP.NET?
Solution 1
The equivalent to a C++ destructor is IDisposable
and the Dispose()
method, often used in a using
block.
See http://msdn.microsoft.com/en-us/library/system.idisposable.aspx
What you are calling a destructor is better known as a Finalizer
.
Here's how you would use IDisposable. Note that Dispose()
is not automatically called; the best you can do is to use using
which will cause Dispose()
to be called, even if there is an exception within the using
block before it reaches the end.
public class MyClass: IDisposable
{
public MyClass()
{
//Do the work
}
public void Dispose()
{
// Clean stuff up.
}
}
Then you could use it like this:
using (MyClass c = new MyClass())
{
// Do some work with 'C'
// Even if there is an exception, c.Dispose() will be called before
// the 'using' block is exited.
}
You can call .Dispose()
explicitly yourself if you need to. The only point of using
is to automate calling .Dispose()
when execution leaves the using
block for any reason.
See here for more info: http://msdn.microsoft.com/en-us/library/yh598w02%28v=vs.110%29.aspx
Basically, the using
block above is equivalent to:
MyClass c = new MyClass();
try
{
// Do some work with 'C'
}
finally
{
if (c != null)
((IDisposable)c).Dispose();
}
Solution 2
There is no way you can control a timing or make a guess on when actually destructor of the object will be called. It's all up to the Garbage Collector
.
The only think you can be sure, in this case, that at the moment you leave that scope the object c
becomes unreachable (I assume there are no global references to that instance inside the scope), so the instance c
is intended to be identified and removed by Garbage Collector
when time comes.
Solution 3
It is up to the garbage collector as to when an object is freed up. However you can force an object to be freed up by calling Finalize. or GC.Collect which will force the garbage collector to take action.
Related videos on Youtube
c00000fd
You can contact me at webdc2000 [ a t ] hotmail.com
Updated on September 16, 2022Comments
-
c00000fd over 1 year
Say, I have my own C# class defined as such:
public class MyClass { public MyClass() { //Do the work } ~MyClass() { //Destructor } }
And then I create an instance of my class from an ASP.NET project, as such:
if(true) { MyClass c = new MyClass(); //Do some work with 'c' //Shouldn't destructor for 'c' be called here? } //Continue on
I'd expect the destructor to be called at the end of the
if
scope but it never is called. What am I missing?-
JustAnotherUserYouMayKnow almost 11 yearsIt will be called when the garbage collector is working, and you can't know when this will happen.
-
bash.d almost 11 yearsIf your class uses unmanaged resources you can use the destructor to release those properly. If it doesn't use managed resources a destructor is rarely ever necessary... Additionally, C# works a little different than usual C++ -> you lose the reference to an object, when the reference goes out of scope when you
new
ed an object. Eventually the GC will destroy the object on the heap. Automatic variables are destroyed when they go out of scope.
-
-
c00000fd almost 11 yearsWell, the whole point of using destructors (in a language I'm familiar with -- C/C++) is to have them called implicitly. If I have to call them explicitly, then I can just be OK with a simple method. So I guess the whole concept of RAII is out of the window in C# too, hah?
-
Darren almost 11 years@c00000fd - C# is a managed language - let the CLR take care of memory allocation for you, it will finalize the object when it deems appropriate. However you can force it via
GC.Collect
like I mention in my answer. -
nunespascal almost 11 yearsThat still doesn't force the garbage collector. Just puts it on a higher priority thread.
-
Darren almost 11 years@nunespascal - according to MSDN it Forces an immediate garbage collection of all generations.
-
c00000fd almost 11 yearsThe reason I need the destructor to be called on that spot is because I need the object (named mutex) to be released on that particular spot. I can't wait for the garbage collector to come in...
-
c00000fd almost 11 yearsOK. Thank you. It explains it. Although it makes destructors almost completely useless in C#.
-
Matthew Watson almost 11 years@c00000fd The equivalent to a C++ destructor is
IDisposable
and theDispose()
method, often used in ausing
block. See msdn.microsoft.com/en-us/library/system.idisposable.aspx What you are calling a destructor is better known as aFinalizer
, and it's quite different from a C++ destructor. -
c00000fd almost 11 years@MatthewWatson: Hmm. Very nice. So how would I add it to my class. Simply deriving it from
IDisposable
and providingpublic void Dispose(){}
doesn't seem to work. TheDispose()
is not called at the end of the if() scope. -
Tigran almost 11 years@c00000fd: will you may think about it like a special event (kind of it) that raised by CLR when your instance is collected, so it may have some use, but surely not in most cases.
-
c00000fd almost 11 yearsOh, I see. I need to have
using
block, right? BecauseDispose
method is not called without it. -
Matthew Watson almost 11 years@c00000fd That's correct, although you could call
c.Dispose()
explicitly yourself if you need to. The purpose ofusing
is to handle automatically calling it. I'll add some more info to the answer in a sec. -
user20358 over 9 yearswhy does the finally block have ((IDisposable)c).Dispose(); instead of just c.Dispose(); . Aren't they both the same thing?
-
Matthew Watson over 9 years@user20358 It's for when the
Dispose()
method has been implemented usingexplicit interface implementation
. In such cases, you have to cast to call it.