When is destructor called for C# classes in ASP.NET?

12,210

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.

Share:
12,210

Related videos on Youtube

c00000fd
Author by

c00000fd

You can contact me at webdc2000 [ a t ] hotmail.com

Updated on September 16, 2022

Comments

  • c00000fd
    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
      JustAnotherUserYouMayKnow almost 11 years
      It will be called when the garbage collector is working, and you can't know when this will happen.
    • bash.d
      bash.d almost 11 years
      If 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 newed an object. Eventually the GC will destroy the object on the heap. Automatic variables are destroyed when they go out of scope.
  • c00000fd
    c00000fd almost 11 years
    Well, 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
    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
    nunespascal almost 11 years
    That still doesn't force the garbage collector. Just puts it on a higher priority thread.
  • Darren
    Darren almost 11 years
    @nunespascal - according to MSDN it Forces an immediate garbage collection of all generations.
  • c00000fd
    c00000fd almost 11 years
    The 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
    c00000fd almost 11 years
    OK. Thank you. It explains it. Although it makes destructors almost completely useless in C#.
  • Matthew Watson
    Matthew Watson almost 11 years
    @c00000fd The equivalent to a C++ destructor is IDisposable and the Dispose() method, often used in a using block. See msdn.microsoft.com/en-us/library/system.idisposable.aspx What you are calling a destructor is better known as a Finalizer, and it's quite different from a C++ destructor.
  • c00000fd
    c00000fd almost 11 years
    @MatthewWatson: Hmm. Very nice. So how would I add it to my class. Simply deriving it from IDisposable and providing public void Dispose(){} doesn't seem to work. The Dispose() is not called at the end of the if() scope.
  • Tigran
    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
    c00000fd almost 11 years
    Oh, I see. I need to have using block, right? Because Dispose method is not called without it.
  • Matthew Watson
    Matthew Watson almost 11 years
    @c00000fd That's correct, although you could call c.Dispose() explicitly yourself if you need to. The purpose of using is to handle automatically calling it. I'll add some more info to the answer in a sec.
  • user20358
    user20358 over 9 years
    why does the finally block have ((IDisposable)c).Dispose(); instead of just c.Dispose(); . Aren't they both the same thing?
  • Matthew Watson
    Matthew Watson over 9 years
    @user20358 It's for when the Dispose() method has been implemented using explicit interface implementation. In such cases, you have to cast to call it.