Timer not set when form

I am trying to understand why Windows.Forms.Timer not hosted when the form created. I have this simple form:

 public partial class Form1 : Form { private System.Windows.Forms.Timer timer; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { timer = new Timer(); timer.Interval = 1000; timer.Tick += new EventHandler(OnTimer); timer.Enabled = true; } private void OnTimer(Object source, EventArgs e) { Debug.WriteLine("OnTimer entered"); } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { this.Dispose(); } } 

When I close it, this.Dispose is this.Dispose , but the timer enable event continues to be this.Dispose . I thought Dispose frees all objects belonging to the located object. This is not true? Does Timer specific behavior?

Currently, I have found that a way to recycle a timer is to make timer.Tick -= OnTimer; - I call it in the Form1_FormClosed event. Is this a good decision or should I do otherwise?

EDIT

Or is it just better to do:

 private void Form1_FormClosed(object sender, FormClosedEventArgs e) { timer.Dispose(); this.Dispose(); } 

?

+4
source share
5 answers

As I said in my previous comment, you should try:

 private Form1_FormClosing(...) { timer.Stop(); timer.Tick -= new EventHandler(OnTimer); } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { timer.Dispose(); timer = null; } 

This is good because you disable the timer again cyclically (in FormClosing), and you can check the other parts (not in this example, because you close the form, but as an example) if this object (timer) was deleted before use.
Therefore, in other parts you can do

 if (timer != null) // Note: this is false if you just use timer.Dispose() { .... } 
+8
source

The only correct way to place disposable members of the IDisposable class is to make it inside your Dispose(bool disposing) method (check the MSDN article). In other words, you can open the autogenerated file Form.Designer.cs and put it in the correct method.

On the other hand, if you add Timer via VS Designer (instead of creating it yourself), it will be added to the components container:

 // autogenerated inside Form.Designer.cs, InitializeComponent() method this.timer = new System.Windows.Forms.Timer(this.components); 

and then correctly positioned when the components element is positioned:

 // autogenerated inside Form.Designer.cs, Dispose(bool disposing) method if (disposing && (components != null)) { components.Dispose(); } 

If you want to do this yourself, keep in mind that the designer does not create an instance of components if he does not consider it necessary. Thus, components can be null in your case.

The easiest way to solve this problem is to add a timer by dragging it from the toolbar, then run it inside the Form_Load handler.

+4
source
  private void Form1_FormClosed(object sender, FormClosedEventArgs e) { timer.Stop(); } 

I should not specify this.Dispose (); In the event closing form, just stop the timer.

+1
source

EventHandler is a permalink, delete the link and stop the timer on the Closing Event or as soon as it is not needed. If you want to check the set timer, check it in a closed event

+1
source

A simple Timer.Dispose() removes timer resources, including stopping the timer from firing in the future.

However, it is possible that after Dispose() returns, there are callbacks that are either actively being executed or are in the working queue of the thread pool that are waiting to be executed.

The second overload Timer.Dispose(WaitHandle) will signal the passed object after all timer callbacks have completed. It can be any WaitHandle , for example a ManualResetEvent .

To simplify the action, you can go to WaitHandle.InvalidHandle , and Timer.Dispose() will return only after all callbacks have completed. This eliminates the need to highlight the true event object and usually what you want to do.

Since WaitHandle is abstract, you need to hack a bit to create your own subclass.

 class InvalidWaitHandle : WaitHandle {} Timer tmr = new Timer(...); tmr.Dispose(new InvalidWaitHandle); 
+1
source

All Articles