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

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?

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();
}

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.

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

Should I dispose old object before assigning new object?

Lets assume we have two class Foo and Bar as given below.
public class Foo
{
public static Bar BarInstance { get; set; }
public static void Main()
{
AssignBar("A");
AssignBar("B");
}
private static void AssignBar(string name)
{
BarInstance = new Bar(name);
}
}
public class Bar : IDisposable
{
public Bar(string name)
{
Name = name;
}
public string Name { get; set; }
protected virtual void Dispose(bool disposing)
{
if (!disposing)
{
return;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
When object A gets replaced by object B. I expect Dispose to called because since there is no reference to Object A exists any more, but it doesn't get called. Could you please explain why?
Should I end up doing CurrentBar.Dispose like below if I want Object A to be disposed.
private static void AssignBar(string name)
{
if (BarInstance != null)
{
BarInstance.Dispose();
}
BarInstance = new Bar(name);
}
It depends on the ownership.
Is Bar given to Foo with the implication that Foo now owns Bar?
If so, then yes, you should call Dispose on the old before assigning a new instance.
Is Bar given to Foo with the implication that it's more of a loan, ie. you can reference and use this object, but it is owned by something else?
If so, then no, you should not call Dispose on the old before assigning a new instance.
Your code is not altogether clear on this point and I would suggest you clean that up, would make it easier to reason about this type in the future.
The way I see it you have 1 of 3 possible scenarios:
Foo always owns Bar. In this case I would put the disposal of the old instance in the setter of the property, or remove the public setter altogether if the only way to get a new Bar instance into it is through the method you have declared.
Foo never owns Bar. In this case I would not add any code that disposes of the old instance, but then I question the existence of that method. In this case it is likely nobody would really own the newly constructed instance.
Foo only owns Bar instances created through your method, but not instances given to it through the public setter. In this case I would add a new field that tracks whether Foo owns Bar or not, and set this to true in the method, and clear it in the property setter.
Dispose is not special in any way, from the C# standpoint it is just another method, as such there is nothing automatic that will call this method.
However, if the object references unmanaged resources, when the object at some point becomes eligible for collection, its finalizer will be executed releasing those unmanaged resources. However, to deterministically release them when you know they are no longer needed, you need to call Dispose.
Dispose is no special method. It will not be called automatically. You'll have to do it.
private static void AssignBar(string name)
{
if(BarInstance!=null)
{
BarInstance.Dispose();
}
BarInstance = new Bar(name);
}
I think you are confusing with finalizers and IDisposable. Finalizers are called at the time of garbage collection(not reliable though). If you have implemented DisposablePattern, then you'll have a Dispose(bool) method which is called from finalizer. Where finalizers are called by GC automatially during garbage collection.
Read here for more info
The runtime won't automatically call Dispose for you, it's your responsibility to ensure it's called. Your object will be garbage collected, but this only ensures that memory is reclaimed. It's up to use to release resources.
You can do this using either a using statement:
using(var x = new BarInstance())
{
// Whatever
}
or you can call it yourself. In your example, since you're replacing the instance you'll need to call Dispose, otherwise you risk a resource leak.
You could opt to use a finalizer in your class, ~Bar. In the finalizer you can dispose of any resources you're holding. However, when the finalizer will be called in non-deterministic, and it's even possible that it will never be called if the garbage collector doesn't kick in.

Destructor never gets called [duplicate]

This question already has answers here:
Why does my destructor never run?
(6 answers)
Closed 9 years ago.
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().
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.
}
}
}
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
Slightly off-topic: You can use Tasks instead of naked threads to run functions without worrying about disposal.
There are multiple issues here:
Setting the variable to null doesn't delete anything, it simply removes a reference to your instance.
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. Orphaned means that any references pointed to by your object are invalid.
You should implement the IDisposable interface and call any cleanup code in the Dispose method. C# and VB offer the using keyword to make disposal easier even in the face of exception.
A typical IDisposable implementation is similar to the following:
class MyClass:IDisposable
{
ClassB _otherClass;
...
~MyClass()
{
//Call Dispose from constructor
Dispose(false);
}
public void Dispose()
{
//Call Dispose Explicitly
Dispose(true);
//Tell the GC not call our destructor, we already cleaned the object ourselves
GC.SuppressFinalize(this);
}
protected virtual Dispose(bool disposing)
{
if (disposing)
{
//Clean up MANAGED resources here. These are guaranteed to be INvalid if
//Dispose gets called by the constructor
//Clean this if it is an IDisposable
_otherClass.Dispose();
//Make sure to release our reference
_otherClass=null;
}
//Clean UNMANAGED resources here
}
}
You can then use your class like this :
using(var myClass=new MyClass())
{
...
}
Once the using block terminates, Dispose() will be called even if an exception occurs.
CLR maintains all the running threads. You will have passed the InstanceMethod of your class to the thread's constructor as either ThreadStart or ParameterizedThreadStart delegate. Delegate will hold the MethodInfo of the method you passed and the Instance of your class in Target Property.
Garbage collector collects and object which should not have any Strong References but your instance is still alive inside Delegate of Thread. So your class is still having the Strong Reference hence it is not eligible for garbage collection.
To prove what I stated above
public class Program
{
[STAThread]
static void Main(string[] args)
{
GcTest();
Console.Read();
}
private static void GcTest()
{
Class cls = new Class();
Thread.Sleep(10);
cls = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
public class Class
{
private Thread _thread;
~Class()
{
Console.WriteLine("~Class");
_thread.Abort();
_thread = null;
}
public Class()
{
_thread = new Thread(ThreadProc);
_thread.Start();
}
private void ThreadProc()
{
while (true)
{
Thread.Sleep(10);
}
}
}
}
Try the above code. Destructor Will not be called. To make it work mark the ThreadProc method as static and run again Destructor will be called

How to Dispose Object instance when it lost it's reference

Using C#.
I have a MainFoo class:
class MainFoo
{
private Foo foo;
public MainFoo()
{
this.foo = new Foo();
}
public CreateNewFoo()
{
this.foo = new Foo();
}
public DoCurrentFoo()
{
this.foo.Do();
}
}
A Foo class:
class Foo
{
~Foo()
{
this.DoEnd();
}
public void Do() {}
private void DoEnd() {}
}
I want to be able to call the method DoEnd() in Foo class whenever private Foo; get's initialized again. This method DoEnd() is private and I would like to keep it that way (so not accessible from MainFoo).
Since the same Foo get's initialized again, I though the instance would loose it's reference so it would call destructor. But this gets only called when MainFoo instance lost reference.
Question: How to dispose object instance when it lost it's reference?
Destructors are not guaranteed to be called at any specific time, or even get called at all. Typically, you should not rely on destructor and should implement IDisposable and call Dispose yourself.
Most conviniently, this can be done with using(...){ }.
Getting back to your sample, you can also dispose object on assignment of property (as Jason Watkins suggested), but make sure that it is not used anywhere else.
public Foo F
{
get{return foo;}
set
{
if( foo != null)
foo.Dispose();
foo = value;
}
}
You cannot, it's the Garbage Collector's job.
From MSDN:
In C#, garbage collection is handled by the common language runtime (CLR) with similar functionality to that of the JVM. The CLR garbage collector periodically checks the memory heap for any unreferenced objects, and releases the resources held by these objects.

Will unassigned object to variable dispose automatically

so lets say we have some thing like this websericeclient object
var myname = new WebServiceClient().GetName ( ) ;
what will happen to this object (WebServiceClient()) is it going to dispose automatically or stay in memory .
"Disposing" (calling IDisposable.Dispose()) has nothing to do with memory. It has to do with freeing unmanaged resources like file or database handles.
What happens when you don't call Dispose() is that these resources will remain until the finalizer is called when the Garbage Collector runs to free the object from memory. If you needed those resources (or if something interesting is meant to happen when they are Disposed()) then you don't want to wait some arbitrary period of time - call Dispose() as soon as you're done with it.
It depends on the _GetName()_ method. And on the _WebServiceClient()_.
Let's take the example:
public class WebServiceClient : IDisposable
{
private static WebServiceClient viciousReference = null;
public WebServiceClient()
{
viciousReference = this;
}
~WebServiceClient()
{
Dispose();
}
public void Dispose()
{
// Standard Dispose implementation
}
}
If your object implements Dispose(), always try to call it yourself. Don't only rely on the garbage collector.

Using `using(...)` effectively useless and/or inefficient?

Does the following code render the using(...) function/purpose irrelevant?
Would it cause a deficiency in GC performance?
class Program
{
static Dictionary<string , DisposableClass> Disposables
{
get
{
if (disposables == null)
disposables = new Dictionary<string , DisposableClass>();
return disposables;
}
}
static Dictionary<string , DisposableClass> disposables;
static void Main(string[] args)
{
DisposableClass disposable;
using (disposable = new DisposableClass())
{
// do some work
disposable.Name = "SuperDisposable";
Disposables["uniqueID" + Disposables.Count] = disposable;
}
Console.WriteLine("Output: " + Disposables["uniqueID0"].Name);
Console.ReadLine();
}
}
class DisposableClass : IDisposable
{
internal string Name
{
get { return myName; }
set { myName = value; }
}
private string myName;
public void Dispose( )
{
//throw new NotImplementedException();
}
}
Output: SuperDisposable
My understanding of the using(...) function is to immediately coerce disposal of the DisposableClass. Yet within the code block, we are adding the class to a dictionary collection. My understanding is that a class is inherently a reference type. So my experiment was to see what would happen to the disposable object added to a collection in this manner.
In this case DisposableClass is still quite alive. Classes are a reference type - so my assumption then became that the collection is not simply referencing this type, but indeed holding the class as a value. But, that didn't make sense either.
So what is really going on?
EDIT: modified code with output to prove that the object is not dead, as might be suggested by some answers.
2nd EDIT: what this comes down to as I've gone through some more code is this:
public void Dispose( )
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool dispose)
{
if (!isDisposed)
{
if (dispose)
{
// clean up managed objects
}
// clean up unmanaged objects
isDisposed = true;
}
}
~DisposableClass( )
{ Dispose(false); }
Stepping through the code (had a breakpoint at private void Dispose(bool dispose)), where false is passed to the method, it becomes imperative that resources are properly disposed of here. Regardless, the class is still alive, but you are definitely setting yourself up for exceptions. Answers made me more curious...
Disposing an object does not destroy it; it simply tells it to clean up any unmanaged resources it uses as they are no longer needed. In your example, you're creating a disposable object, assigning to a dictionary, and then just telling it to remove some resources.
The correct scenario for the using statement is when you want to initialize a resource, do something with it, and then destroy it and forget about it; for example:
using (var stream = new FileStream("some-file.txt"))
using (var reader = new StreamReader(stream))
{
Console.Write(reader.ReadToEnd());
}
If you want to retain the object after you've used it, you shouldn't be disposing it, and hence a using statement should not be used.
You should not be using a using block in this case, since you need the object after the block has finished. It is only to be used when there is a clear starting and ending point of the lifetime of the object.
It's important to remember that IDisposable, while a slightly special interface, is an interface nonetheless. When the using block exits, it calls Dispose() on your object. Nothing more. Your reference is still valid and, if your Dispose method does nothing, your object will be completely unaffected. If you don't keep track the disposal and explicitly throw exceptions, then you won't get any exceptions after that point because there is no inherent disposed state in .NET.
The IDisposable interface indicates that a type manages some kind of resource. The Dispose method exists to allow you to dispose of the resources used by an instance without having to wait for garbage-collection to take place and the resources to be freed by a finalizer.
In your example, the dictionary is still containing a reference to the disposable class, but the instance will have been disposed at the end of the using block. Subsequent attempts to call methods on the instance will now likely throw ObjectDisposedException or InvalidOperationException, to indicate the instance is no longer in a "working" state.
Disposing an IDisposable is not to be confused with releasing the memory occupied the instance, or invoking any garbage-collection routines on it. The instance is tracked and managed by the garbage-collector like any other, only to be released when the garbage-collector decides it.

Categories