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().
Related
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();
}
}
}
Actually I m trying to close my window by firing the event from my ViewModel. Everything works fine and awesome, but I know that I must unsbscribe my event to avoid memory leaks. thus I implement the IDisposable interface and I unsbscribe the event inside the Dispose method.
Below is my code :
public partial class MainWindow : Window, IDisposable
{
private MainViewModel viewModel;
public MainWindow()
{
InitializeComponent();
DataContext = viewModel = new MainViewModel();
this.viewModel.RequestClose += CloseWindow;
}
void CloseWindow(object sender, EventArgs e)
{
this.Close();
}
public void Dispose()
{
////here we need to unsubscribe the event
this.viewModel.RequestClose -= this.CloseWindow;
}
}
What I need to know :
Is that code correct
When the GC will be called and excute the dispose method
Is there a better way to do such a thing
but I know that I must unsbscribe my event to avoid memory leaks
Memory leak occurs, when short-lived object subscribes an event of long-lived objects (or static event), and does not unsubscribe later (e.g., see this answer). I suppose, that this is not your case.
When the GC will be called and excute the dispose method
GC doesn't call IDisposable.Dispose (e.g., see this answer). At all.
If you haven't any code, that calls MainWindow.Dispose explicitly, it will be called never.
Is there a better way to do such a thing
I'd avoid IDisposable and events. Attached behavior here is more convenient, IMO (at least, this is reusable):
public static class WindowClosingBehavior
{
public static bool GetIsClosingInitiated(DependencyObject obj)
{
return (bool)obj.GetValue(IsClosingInitiatedProperty);
}
public static void SetIsClosingInitiated(DependencyObject obj, bool value)
{
obj.SetValue(IsClosingInitiatedProperty, value);
}
public static readonly DependencyProperty IsClosingInitiatedProperty = DependencyProperty.RegisterAttached(
"IsClosingInitiated",
typeof(bool),
typeof(WindowClosingBehavior),
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, IsClosingInitiatedChanged));
private static void IsClosingInitiatedChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
{
var window = target as Window;
if (window != null && (bool)e.NewValue)
{
window.Close();
}
}
}
Somewhere in window's XAML:
behaviors:WindowClosingBehavior.IsClosingInitiated="{Binding IsClosingInitiated}"
where IsClosingInitiated is a property from view model:
public class SomeViewModel
{
// ...
private void Foo()
{
// ...
IsClosingInitiated = true;
}
}
You only need to unsubscribe events when the source and the handler have different lifetimes, otherwise they both go out of scope at the same time and they are garbage collected together.
So in this case IDisposable is not needed. Anyway if you implement IDisposable you need to explicitly call it, otherwise you don't have control about when it is called.
Actually when the Window.CloseWindow subscribe to the event, it makes the view model point to the window.
The reverse is also true because there is a ViewModel field in the Window.
Both window and view model reference to each other.
If there is no other reference to them, garbage collection will make the job.
Dispose will be called if some code calls it.
To my knowledge, it won't happen, unless you surround the creation of the windows with a using or explicitly call Dispose
The best way here is to not implement IDisposable / Dispose : keep it simple.
Regards
I'd say using an event is a more than acceptable method of achieving this. For a more complete dispose pattern, use the following snippet:
#region IDisposable
//Dispose() calls Dispose(true)
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// NOTE: Delete the finalizer if this class doesn't
// own unmanaged resources itself.
~ClassName()
{
//Finalizer calls Dispose(false)
Dispose(false);
}
//The bulk of the clean-up code is implemented in Dispose(bool)
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
//free managed resources (Example below)
if (managedResource != null)
{
managedResource.Dispose();
managedResource = null;
}
}
//Free native resources if there are any. (Example below)
if (nativeResource != IntPtr.Zero)
{
Marshal.FreeHGlobal(nativeResource);
nativeResource = IntPtr.Zero;
}
}
#endregion
In your case, your dispose method will be this:
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~MainWindow()
{
Dispose();
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (viewModel != null)
{
viewModel.RequestClose -= CloseWindow;
viewModel.Dispose();
viewModel = null;
}
}
}
As pointed out by Dennis, you'll need to keep the finalizer to ensure that Dispose gets called when the MainWindow is closed, for example in the event of the application being exited.
Registering for an event on FileSystemWatcher causes the registering class to stay in memory even after eliminating all (my) references to the FileSystemWatcher and letting the GC and finalizers run. I've constructed an example below showing how an object using FileSystemWatcher stays in memory while another set of objects (of type A and B) which use similar events/eventhandlers do not stay in memory.
Example
class Program
{
class UsesFileWatcher
{
public FileSystemWatcher fw;
public UsesFileWatcher()
{
fw = new FileSystemWatcher(#"C:\", "*.txt");
fw.Changed += eventHandler;
fw.EnableRaisingEvents = true;
}
void eventHandler(object sender, FileSystemEventArgs e)
{
}
}
// For Comparison, I have classes A and B which use similar events and event handlers
class A
{
public event EventHandler AEvent;
}
class B
{
public A a;
public B()
{
a = new A();
a.AEvent += eventHandler;
}
void eventHandler(object sender, EventArgs e)
{
}
}
static void Main(string[] args)
{
var weakRefToB = WeakReferenceToB();
var weakRefToUsesFileWatcher = WeakReferenceToUsesFileWatcher();
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("B Alive = {0}", weakRefToB.IsAlive);
Console.WriteLine("UsesFileWatcher Alive = {0}", weakRefToUsesFileWatcher.IsAlive);
Console.ReadKey();
}
static WeakReference WeakReferenceToB()
{
return new WeakReference(new B());
}
static WeakReference WeakReferenceToUsesFileWatcher()
{
return new WeakReference(new UsesFileWatcher());
}
}
Notes:
I understand that FileSystemWatcher implements IDisposable and that I should be calling Dispose() when I'm done with it. But my understanding is that if I miss the call to Dispose() that it just means that the work it needed to do would be done later during the finalizer.
There is a known FileSystemWatcher memory leak documented here. But the description sounds different than what I'm describing.
I used Red Gate's ANTS Memory Profiler to show what is keeping it alive:
Question:
Is this a bug in FileSystemWatcher or are my expectations incorrect somehow?
Of course it's not a bug. You can see right in the profiler that the object is being referenced. There's a system type that is rooted that has a callback tot he FSW, making it accessible from a rooted object.
It will remove those callbacks when it is disposed of, enabling it to be collected, so you'll need to dispose it if you want it to be eligible for collection.
I have a WPF application and I need to listen to, and handle events for the lifetime of the application for a certain class.
Is it bad practice to create a wrapper class, create a static instance of it and call "StartListening()"? What if an unhanded exception happens on this static instance? Will it tear down the entire application as it would in an ASP.NET application?
Should I QueueUserWorkItem, create the class, attach events, and then put some kind of while(true){} statement to keep the thread alive?
What is the best practice?
To me this seems like a classic publisher/listener problem.
I would create an interface: IMyClassNameEventListener and make MyClass take an instance of it as a constructor parameter. Then in the constructor I would call the Attach(MyClass obj) method on the interface instance. Of course, the listener would have a singleton lifecycle, it doesn't need to be static.
A slightly better approach would be to use a factory to create instances of MyClass which would then do the attaching, so the Attach call and the dependency are out of the constructor.
Wether the app would fail would be dependent on how you start the listener. You can look into the TaskFactory class, it provides options to handle exception propagation. How would you want the app to behave if the listener fails?
Of course in the listener object itself, you only need to have code run when there is something to handle. So, when you receive an event, you startup a thread. You can use a queue of actions if you'd want to have only one thread running.
Inside the listener class, you might want to have something like the following:
private Queue<Action> ActionQueue = new Queue<Action>();
private object LockObj = new Object();
private volatile bool IsRunning;
public void Attach(Class1 obj)
{
obj.SomeEvent += this.HandleEvent;
}
private void HandleEvent(object sender, EventArgs e)
{
lock(this.LockObj)
{
this.ActionQueue.Enque(() => this.Handle(sender, e));
if (!this.IsRunning)
{
Task.Factory.StartNew(() => this.Loop() );
}
}
}
private void Loop()
{
this.IsRunning = true;
while ((Action action = this.DequeueAction()) != null)
action();
this.IsRunning = false;
}
private Action DequeueAction()
{
lock (this.LockObj)
{
return this.ActionQueue.Count > 0 ? this.ActionQueue.Dequeue() : null;
}
}
private void Handle(object sender, EventArgs e)
{
//handling code
}
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.