C# Destructor not calling after out of scope - c#

I have problem with destructor after going out of scope(it is calling but after some time and need to make an action on form, for example change radio button), maybe there's mistake in my code. Take a look:
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
EventLogger.Print += delegate(string output)
{ if (!textBox1.IsDisposed) this.Invoke(new MethodInvoker(() => textBox1.AppendText(output + Environment.NewLine)), null); };
}
private void button1_Click(object sender, EventArgs e)
{
TestClass test = new TestClass();
}
}
public static class EventLogger
{
public delegate void EventHandler(string output);
public static event EventHandler Print;
public static void AddLog(String TextEvent)
{
Print(TextEvent);
}
}
public class TestClass
{
public TestClass()
{
EventLogger.AddLog("TestClass()");
}
~TestClass()
{
EventLogger.AddLog("~TestClass()");
}
}
}

Right, because this isn't C++. The finalizer (not destructor as in C++) is not guaranteed to be called immediately after an object has left its declaring scope, it is called when the GC decides to swoop in and clean up after you.
May I ask why you are using a finalizer to begin with? Are you maintaining references to unmanaged resources which need to be deallocated as deterministically as possible (if so, read up on the IDisposable interface)? The use cases for C# finalizers are few and far between, it's not common to implement them.

C# is not C++. Destructors don't run synchronously.
There is no bugs in your code as is, but it looks like you may need to implement "IDisposable pattern" for your class to provide a way for caller to guaranty that some destruction of your object is executed synchronously.

For those of us who are more comfortable with the C++ pattern it's useful to check out the docs for the IDisposable interface:
http://msdn.microsoft.com/en-us/library/system.idisposable.aspx
Unfortunately I've just tried it and it's not working as I'd like. I used an automatic object to save the current state of the GUI cursor, switch to the wait cursor and restore the original cursor as the object goes out of scope. The IDisposable interface does result in the cursor being restored but not immediately - so the Wait Cursor is showing for too long. Too bad because this is a very useful pattern.
Update: The C# try/finally pattern is comfortable enough after a while:
public void do_something_time_consuming()
{
ShowBusyCursor cursor = new ShowBusyCursor();
try
{
...
return;
}
finally
{
cursor.done();
}
}

The finalizer is not designed to be called immediately after going out of scope. It is called when the object is garbage-collected, which be may anywhere from milliseconds to days after going out of scope.
The finalizer is NOT meant for this kind of code. It is only for resource cleanup.
You can't force it to do something immediately after going out of scope, but you can tell it to immediately before going out of scope, with a Close() or similar method to signal that the object is done being used.
For example:
private void button1_Click(object sender, EventArgs e)
{
TestClass test = new TestClass();
// do stuff
test.Close();
}
Note: You could implement IDisposable, as has been suggested, but this use doesn't exactly fit the intended use of IDisposable, so although it would work, it's a bit hackish.

Related

Why should you implement IDisposable to clean up unmanaged resources only?

The documentation says
You should implement IDisposable only if your type uses unmanaged resources directly.
Coming from a mostly Java background, this sounds strange to me. Suppose I have a class that contains an IDisposable member:
class Foo : IDisposable {
private StreamWriter sw;
...
}
... and suppose this class is used, for example, as a sort of filter that takes strings and modifies them and then outputs them with the StreamWriter sw. I want to use this class like a sort of Writer.
Why wouldn't I want to implement Dispose(bool) which would call sr.Dispose()? This is what I would have to do if I were coding it in Java (the Java Closable interface is similar to .NET's IDisposable, though in some ways different). Yet the documentation says I shouldn't, because I'm not directly using unmanaged resources.
If I don't override Dispose(bool), how does the managed resource sw get disposed when I leave the block started by the using statement?
You should implement IDisposable when your class contains an IDisposable field such as for example a StreamWriter.
In this case you can assume that your type does use unmanaged resources (through the StreamWriter class) under the hood, and you should always dispose any object that implements the IDisposable interface as soon as you are done using them.
Why wouldn't I want to implement IDisposable(bool) which would call sr.Dispose()?
You certainly would.
If I don't override Dispose(bool), how does the managed resource sw get disposed when I leave the block started by the using statement?
It doesn't. The underlying unmanaged resource(s) may eventually be released by the finalizer (depending on the implementation of the IDisposable class) but the managed object won't be disposed unless you explicitly dispose it in your class.
When you use an instance that implements the IDisposable interface, it's best practice to use it as a local variable inside a using statement.
However, that's not always possible.
In some cases you must include a field that implements the IDisposable interface. In these cases, you should also implement it yourself and dispose them in your class Dispose(bool) method.
For instance, Suppose you want to schedule a task. One fairly easy implementation is to use a class that contains a System.Timers.Timer field, a start, stop, and doWork method.
In such a case you can't use the timer as a local variable, it must be a field, and therefor your class should implement the IDisposable interface and dispose the timer on it's Dispose(bool) method.
Here is a simplified code example (a bit too simplified, I guess, but good enough for this demonstration)
public abstract class Schedualer : IDisposable
{
private Timer _timer;
public Schedualer(double interval)
{
_timer = new Timer(interval);
_timer.Elapsed += _timer_Elapsed;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (_timer != null)
{
_timer.Elapsed -= _timer_Elapsed;
_timer.Dispose();
}
}
}
protected abstract void OnTimerElapsed();
protected void StartTimer()
{
_timer.Start();
}
protected void StopTimer()
{
_timer.Stop();
}
private void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
_timer.Stop();
try
{
TimerElapsed();
}
finally
{
_timer.Start();
}
}
}

Close WinForm Application from different Form

This may seem like a silly question, but I just want to make sure I have it right. My main form is not visible most of the time. To open it I have a NotifyIcon. One of the menu options is Exit Application. I also have a few static global variables that need to be disposed of before the application closes. so in program.cs i have this.
[STAThread]
static void Main()
{
InitializeApplication();
InitializeMainForm();
Application.Run(main);
}
private static void InitializeApplication()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.ApplicationExit += Application_ApplicationExit;
}
private static void InitializeMainForm()
{
main = new AssignButtonForm();
main.FormClosing += main_FormClosing;
Globals.StartNotify();
}
static void main_FormClosing(object sender, FormClosingEventArgs e)
{
var dlg = MessageBox.Show("Turn off Application?", "Exit?", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);
if (dlg == DialogResult.OK)
{
Globals.notifyIcon1.Dispose();
Application.Exit();
}
else
{
e.Cancel = true;
}
}
So what i'm hoping is that this is the correct way to call that.
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Hide();
Application.OpenForms[0].Close();
}
is that correct? or is there a better way?
EDIT
ok so one of my classes that has its own Dispose method
public class KeymonNotifyIcon : IDisposable
{
public KeymonNotifyIcon()
{
InitializeComponent();
keymonMenuStrip.SetupKeysSelected += OnSetupKeysSelected;
}
~KeymonNotifyIcon()
{
Dispose();
}
public void Dispose()
{
if (notifyIcon1 != null)
notifyIcon1.Dispose();
if (keymonMenuStrip != null)
keymonMenuStrip.Dispose();
}
}
The global class
public static class Globals
{
public static TraceSource trace = new TraceSource("Keymon");
public static KeymonNotifyIcon notifyIcon1;
public static void StartNotify()
{
notifyIcon1 = new KeymonNotifyIcon();
}
}
Actually, I am fairly certain that Application.Exit will call all of your Dispose methods for you (as long as you have implemented IDisposable
See this question, which references this question
If your program just shuts down, objects that have not been garbage collected will have their finalizers run. It is the recommended pattern that objects implementing IDisposable have a finalizer to ensure that IDisposable is run. To the best of my knowledge, .NET BCL classes always follow that pattern. However, your own or third-party/open source components might not follow that pattern.
Note: The linked pattern on MSDN does not call GC.SuppressFinalize. Check out how to use it to reduce the GC overhead.
Implementing IDisposable alone isn't sufficient to ensure that the object is properly disposed.
If you have statically referenced objects that implement IDisposable, it is a more solid solution to explicitly call IDisposable.Dispose() on them from an application shut down event.
EDIT
Your Dispose implementation will cause Dispose() to be called twice on the owned objects because:
if (notifyIcon1 != null)
notifyIcon1.Dispose();
does not set notifyIcon1 to null, and the finalizer unconditionally calls Dispose() again.
Additionally, you will always cause the finalizer to run (which makes GC more expensive for that class) because you do not call GC.SuppressFinalize() in Dispose().

Garbage Collection for List Objects

I would like to ask what is the efficiency way the clean and dispose the object collected in the List (Of Object)?
Is that by calling the List.Clear() method will automatic clean all the object collected by it?
For Example consider the below example
public partial class Form1 : Form
{
FontCollection m_fontCollection;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
m_fontCollection = new FontCollection();
for (int i = 0; i < 5000; i++)
{
Font font = new Font("Arial", 23);
FontImpl impl = new FontImpl(font, Color.Black);
impl.AfterChange +=
new FontImpl.AfterChangeHandler(impl_AfterChange);
m_fontCollection.Add(impl);
}
m_fontCollection.Dispose();
MessageBox.Show("TakeSnap");
}
void impl_AfterChange()
{
throw new NotImplementedException();
}
}
public class FontCollection : IEnumerable, IDisposable
{
IList<FontImpl> m_Implementation = new List<FontImpl>();
internal void Add(FontImpl impl)
{
this.m_Implementation.Add(impl);
}
public IEnumerator GetEnumerator()
{
return this.m_Implementation.GetEnumerator();
}
public void Dispose()
{
m_Implementation.Clear();
m_Implementation = null;
}
}
public class FontImpl
{
private Font m_Font;
private Color m_color;
public FontImpl(Font newFont, Color newColcor)
{
m_Font = newFont;
m_color = newColcor;
}
public event AfterChangeHandler AfterChange;
public delegate void AfterChangeHandler();
}
When i run the above application ANTS memory profiler i could see the memory leaks Font and FontFamily (I could not able to upload the screen) and how to remove these leaks
In general, you shouldn't need to worry about garbage collection, and when it occurs. An object is eligible for GC when there are zero references to it.
The thing you should pay attention to, however, are IDisposable objects. When you are finished with an IDisposable object, you really need to be calling Dispose() on it. If the object lives within the local scope of a functinon, then a using block makes this easy:
using (var resource = new SomeIDisposable()) {
// use resource
// resource.Dispose() is automatically called, *even if* an exception
// is thrown.
}
You can cause memory leaks by ending up with "dangling references" to objects, which prevent them from being garbage collected. Most often the cause of this is with event handlers. When you subscribe to an event exposed by object A, with an event handler on object B, A gets a reference to B:
class B {
void hook_up_to(A a) {
a.SomeEvent += Handler; // `a` gets a reference to `this`
}
void Handler(object sender, EventArgs e) {
}
}
class Program {
private A _a = new A();
static void SomeMethod() {
var b = new B();
b.hook_up_to(_a); // _a now has a reference to b
// b goes out of scope.
}
}
Normally, when b goes out of scope, the object it references would be eligible for garbage collection. In this case though, b hooked up to an event published by member variable _a, which caused _a to gain a reference to b. Now there is one outstanding reference to b, which is impossible1 to clear, and b is ineligible for GC. This is a memory leak.
1 The only way reference to b in this case is this pointer if/when the event handler is fired.
You don't need to implement IDisposable on your class. In general the only time your class needs to implement IDisposable is when it contains other classes that need to be disposed of (things like database and network connections, and unmanaged objects).
In your example, you might want to consider making m_fontCollection a local variable within button1_Click, since you're creating and disposing of it entirely within that method. If you make it local, then it will be garbage-collected once button1_Click exits ... provided there are no remaining references to it (which indeed there are not in this case).
Clear just removes everything from the list. In your case you have a list of IDisposable objects and you need to call Dispose on all the items in the list. Calling Clear does not do that.
Your FontImpl should implement IDisposable since it manages an IDisposable object:
public void Dispose() {
if (m_Font != null) {
m_Font.Dispose();
m_Font = null;
}
}
And your FontCollection Dispose should look like this:
public void Dispose()
{
foreach(FontImpl font in m_Implementation) {
font.Dispose();
}
m_Implementation.Clear();
m_Implementation = null;
}
In the case of the code you have shown you have Font objects which implement IDisposable and thus should be disposed. Those objects are being managed by your FontImpl class and so FontImpl should implement IDisposable. Your FontCollection class contains a list of FontImpl objects which should now be disposable and so FontCollection needs to implement IDisposable.
You should read up on the IDisposable pattern (this SO answer gives some great information - https://stackoverflow.com/a/538238/416574).
That being said, from the code snippet you provided it does not appear that you gain anything from your FontCollection other than a class to wrap a list. Unless there are other things you are going to do with that class I would just have a list as a member variable. That way in the Dispose method of your form you can walk your list and dispose the FontImpl objects. If you want to protect from double disposing, then just empty the list after disposing everything.

Custom initialization functions with IDisposable

In .NET (C#) I follow some custom conventions and patterns that require Constructors, Initialization functions and IDisposable implementations. A typical class is illustrated below. No initialization is done directly in the constructor but rather through a dedicated function that is supposed to make the object reusable. However, I am not sure what happens when Dispose gets called. If the GC calls it, the reference to the object is lost anyways so no worries there. If it is explicitly called, are there any drawbacks simply calling Initialize and treating the class as a fresh object since GC.SupressFinalize has been called? Lol, I'm sure I could have asked this in an easier way.
public abstract class Thread: System.IDisposable
{
protected bool Disposed { get; set; }
protected bool Terminate { get; private set; }
public bool IsRunning { get; private set; }
private System.Threading.Thread ThreadObject { get; set; }
public Thread ()
{
this.Initialize();
}
~Thread ()
{
this.Dispose(false);
}
public virtual void Initialize ()
{
this.Stop();
this.Disposed = false;
this.Terminate = true;
this.IsRunning = false;
this.ThreadObject = null;
}
//====================================================================================================
// Functions: Thread
//====================================================================================================
public void Start ()
{
if (!this.IsRunning)
{
this.IsRunning = true;
this.Terminate = false;
this.ThreadObject = new System.Threading.Thread(new System.Threading.ThreadStart(this.Process));
this.ThreadObject.Start();
}
}
/// <summary>
/// Override this method to do thread processing.
/// [this.Terminate] will be set to indicate that Stop has been called.
/// </summary>
/// <param name="template"></param>
protected abstract void Process ();
public void Stop (System.TimeSpan timeout)
{
if (this.IsRunning)
{
this.Terminate = true;
try
{
if (timeout.TotalMilliseconds > 1D)
{
this.ThreadObject.Join(timeout);
}
else
{
this.ThreadObject.Join();
}
}
catch
{
try
{
this.ThreadObject.Abort();
}
catch
{
}
}
this.ThreadObject = null;
this.IsRunning = false;
}
}
//====================================================================================================
// Interface Implementation: System.IDisposable
//====================================================================================================
public void Dispose ()
{
this.Dispose(true);
System.GC.SuppressFinalize(this);
}
protected virtual void Dispose (bool disposing)
{
if (!this.Disposed)
{
if (disposing)
{
// Dispose managed resources.
this.Stop(System.TimeSpan.FromSeconds(1));
}
// Dispose unmanaged resources here.
// Note disposing has been done.
this.Disposed = true;
}
}
}
The GC never calls Dispose, it's up to the consuming code. The GC does however call the finalizer. This is used in the best practice IDisposable implementation to clean up unmanaged code only.
Where Dispose is used outside of the context of a finalizer, then there is no need for the GC to call the finalizer, and therefore SuppressFinalize is used as an optimisation to prevent it happening twice.
If the object is reused this causes an issue. Technically you can re-register the finalizer on initialization, but this would need to be made thread safe. Common practice is that an object is not reused after it has been Disposed, and typically the Dispose method should only execute exactly once. IMO the initializer method and object reuse introduces complexities to the pattern that move it away from it's intended purpose.
There's no technical reason why you can't reactivate a disposed object in this way, though I woudln't do it as it's against the principle of least surprise (most disposable objects are used once).
If you really do want to go this way, I'd avoid having a finalizer, which means your IDisposable class must not directly own any unmanaged resources. You can do this by wrapping any unmanaged resources your class uses in a manged wrapper (e.g. look at the SafeHandle class for an example).
I don't like all the precise details of your thread handling, but if you are going to have a class where each instance owns a thread, you should provide a Dispose method which will ensure that the instance's thread dies off in an orderly fashion.
If you want to allow for the thread to get cleaned up even when an object is abandoned, you'll probably have to create a wrapper object to which the outside application holds a reference but your thread does not. The Finalize() method for that wrapper object should nudge the thread in such a way that it will die off. The thread could simply poll a flag every few seconds to see if it should exit, or there could be a more sophisticated termination strategy.
I'm confused, though, why Initialize calls Stop()? I would have expected it to call Start().
Wrong language pattern appication sample is used in the code. I clearly see C++ backgroung for the C# code author. Unfortunately C++ coding techniques in not applicable in C# language.
Better not to allow object to get into garbage collector (GC), simply referencing it somewhere else, as in the Singleton pattern, rather that trying to resurrect disposed object, or use Dispose pattern in a language not allowing full control for the garbage collector and memory management, as is to be true, for example, in C++.
Simply, you should not use C++ idioms in C#, but the tips and tricks are:
Interfaces instead of pure virtual functions in C++,
Interface inheritancee instead of multiple class inheritance in C++,
No memory management (use weak references) instead of full controlled object lifetime in C++

Object doesn't get garbage collected

I think this is a C# beginner question, but I can't seem to find a correct solution.
I have a ClassOne object, which defines an event.
I create a ClassTwo object, which is considered as a black box, which means I don't know whether it will register to any event or not. ClassTwo constructor registers to the event of ClassOne.
The problem comes, when ClassTwo object goes out of scope. The garbage collector never deletes this object, because it never deregistered the event.
So I have two questions:
Is there a way for ClassTwo object to know, when it goes out of scope? For an old C++ programmer this would be in the destructor, but with C# this doesn't work.
Is there a debug tool which helps me to find such objects?
Here is a sample code to reproduce the issue:
public partial class MainWindow : Window
{
static public ClassOne classOne = new ClassOne();
public MainWindow()
{
InitializeComponent();
ClassTwo classtwo = new ClassTwo();
}
private void buttonTest_Click(object sender, RoutedEventArgs e)
{
GC.Collect();
}
}
public class ClassOne
{
public ClassOne()
{
Trace.WriteLine(this + " constructor");
}
~ClassOne()
{
Trace.WriteLine(this + " destructor");
}
public delegate void UpdateFunc(object sender, EventArgs args);
public event UpdateFunc OnUpdate;
}
public class ClassTwo
{
public ClassTwo()
{
Trace.WriteLine(this + " constructor");
MainWindow.classOne.OnUpdate += new ClassOne.UpdateFunc(classOne_OnUpdate);
}
void classOne_OnUpdate(object sender, EventArgs args)
{
throw new NotImplementedException();
}
~ClassTwo()
{
Trace.WriteLine(this + " destructor");
}
}
I would implement IDisposable on an object like this and unregister from the event in the Dispose method.
You would use your object like this:
using(var two = new ClassTwo(classOne))
{
// Do something with two
}
// object can now be garbage collected.
If the caller fails to call Dispose, you are out of luck.
Not unless it implements IDisposable and the caller cooperates by calling Dispose correctly.
(Of course, why wouldn't the caller cooperate?)
Not that I've of. :( I think your best bet is to implement IDisposable and unregister on Dispose.
As other people have mentioned, the Dispose pattern is the way to address this issue. If the ClassTwo object lives for a short time, you can use the C# using statement to ensure Dispose is called after you are finished using the object:
using (var foo = new ClassTwo())
{
foo.Bar();
}
In order to find the root cause of such issues, you need to use a memory profiler. dotTrace has already been mentioned, and another good one is the SciTech Memory Profiler. What you need to find is the Root Path to the object that you think should be garbage collected, but isn't. The root paths are the reason why the object is not being collected - because through transitive references, an object that's guaranteed to be alive (a GC Root) is referencing your object that you want to be dead.
These memory profilers are very helpful in identifying which GC roots are causing you trouble, and what the reference paths are from the root to your object. Somewhere along that root path will be a reference that is out of place, and is the cause of the problem.
In your code, the cause of the ClassTwo object not being collected could be either the fact that MainWindow has a static reference to the ClassOne object, or that the event handler from ClassOne to ClassTwo has not been unhooked. Static references are one example of GC Roots - so everything classOne references will be alive until that static reference in MainWindow is changed.
Whether the static or the event handler is the problem depends on the scenario of your application - should the ClassOne object also be collected - is it wrong to have a static reference to it? Or is the static reference desired behaviour - is classOne a long lived object and classTwo a short lived one, in which case, classTwo should be Disposed when its life is over, and the Dispose should unhook the event handler.
This is a good article to learn about the .Net GC, written by Jeffrey Richter: http://msdn.microsoft.com/en-us/magazine/bb985010.aspx. It's a bit old now, there have been new additions to the GC over recent years, but it's a great place to start.

Categories