Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Destructor never gets called [duplicate]

I have a class Class that creates a Thread in it's constructor. This thread runs a while(true) loop that is reading non-critical data from a NetStream. The thread will be aborted by the destructor:

~Class()
{
 _thread.Abort();
 _thread = null;
}

When the program wants to end the use of Class's instance - ClassInstance, it calls:

ClassInstance = null;
GC.Collect;

I thought that means that ~Class() will be caller automatically at that point - but it's not.

This thread keeps running even after Application.Exit() and returning from Main().

like image 847
Edgar James luffternstat Avatar asked Aug 28 '13 13:08

Edgar James luffternstat


People also ask

Why is my destructor not being called?

There are two reasons that your destructors aren't being called, one is as kishor8dm pointed out that you are using the operator "new" and because of that the "delete" command must be called explicitly.

Why is destructor being called twice?

The constructor code is the construction of t1. Then a copy constructor is used when it is pushed back on the vector. When the clear() is called, it calls the destructor for the object in the vector. Then t1's destructor is called when it goes out of scope.

Why did the destructor not execute C#?

The destructor will only get called when the garbage collector decides to collect your instance. The garbage collector runs infrequently, typically only when it detects that there is memory pressure. The garbage collector collects ONLY orphaned collections.

Why is my destructor being called C++?

Destructors are called when one of the following events occurs: A local (automatic) object with block scope goes out of scope. An object allocated using the new operator is explicitly deallocated using delete . The lifetime of a temporary object ends.


2 Answers

The crucial bit of your code is not included; how the thread is started and what method it is running. If I had to make a guess I would say it is likely you started the thread by passing an instance method of Class. So basically your class instance is still rooted by the running of the thread. You attempt to stop the thread in the finalizer, but the finalizer will never run because the instance is still rooted leading to a catch-22 situation.

Also, you mentioned that the thread is running non-critical code and that was your justification for using Thread.Abort. That really is not a good enough reason. It is very hard to control where that ThreadAbortException will get injected into the thread and as a result it may corrupt critical program data structures you did not anticipate.

Use the new cooperative cancellation mechanisms included with the TPL. Change the while (true) loop to poll a CancellationToken instead. Signal the cancellation in the Dispose method when you implement IDisposable. Do not include a finalizer (destructor in C# terminology). Finalizers are intended to be used to clean up unmanaged resources. Since you have not indicated that unmanaged resources are in play then it is pointless to have a finalizer. You do not have to include a finalizer when implementing IDisposable. In fact, it is considered bad practice to have one when it is not really needed.

public class Class : IDisposable
{
  private Task task;
  private CancellationTokenSource cts = new CancellationTokenSource();

  Class()
  {
    task = new Task(Run, cts.Token, TaskCreationOptions.LongRunning);
    task.Start();
  }

  public void Dispose()
  {
    cts.Cancel();
  }

  private void Run()
  {
    while (!cts.Token.IsCancellationRequested)
    {
      // Your stuff goes here.
    }
  }
}
like image 156
Brian Gideon Avatar answered Oct 05 '22 23:10

Brian Gideon


If you implement IDisposable, and dispose the object, then the code in Dispose will run, but there is no guarantee that Destructor will also be called.

Garbage Collector forms an opinion that it is a waste of time. So if you want to have a predictable dispose you can use IDisposable.

Check this Thread

like image 39
Rahul Tripathi Avatar answered Oct 06 '22 01:10

Rahul Tripathi