Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Windows Forms Timer doesn't stop. How is that possible?

During debugging I can see that after Timer.Stop() or Timer.Enabled = false commands are executed, Timer is still running (Timer.Enabled = true). How is that possible?

like image 439
Peter17 Avatar asked Dec 16 '22 11:12

Peter17


2 Answers

This is possible when you stop the timer on a worker thread. For example:

public partial class Form1 : Form {
    public Form1() {
        InitializeComponent();
    }
    Timer timer1;
    protected override void OnLoad(EventArgs e) {
        base.OnLoad(e);
        timer1 = new Timer();
        timer1.Interval = 3000;
        timer1.Start();
        var t = new System.Threading.Thread(stopTimer);
        t.Start();
    }
    private void stopTimer() {
        timer1.Enabled = false;
        System.Diagnostics.Debug.WriteLine(timer1.Enabled.ToString());
    }
}

Output:
True

The timer must be stopped by the UI thread, the class takes care of it automatically. Quite similar to Control.BeginInvoke(). There's an explicit race, the Tick event handler can run after you stopped it. This can also happen on the UI thread if the very first timer you create is created on a worker thread. A splash screen for example. That's not healthy, you ought to fix that.

like image 72
Hans Passant Avatar answered Jan 09 '23 12:01

Hans Passant


Calling Start after you have disabled a Timer by calling Stop will cause the Timer to restart the interrupted interval. If your Timer is set for a 5000-millisecond interval, and you call Stop at around 3000 milliseconds, calling Start will cause the Timer to wait 5000 milliseconds before raising the Tick event.

bear also in mind

Calling Stop on any Timer within a Windows Forms application can cause messages from other Timer components in the application to be processed immediately, because all Timer components operate on the main application thread. If you have two Timer components, one set to 700 milliseconds and one set to 500 milliseconds, and you call Stop on the first Timer, your application may receive an event callback for the second component first. If this proves problematic, consider using the Timer class in the System.Threading namespace instead.

http://msdn.microsoft.com/en-us/library/system.windows.forms.timer.stop.aspx

like image 42
Massimiliano Peluso Avatar answered Jan 09 '23 13:01

Massimiliano Peluso