Alex Alex - 21 days ago 5
C# Question

How to stop System.Timers.Timer

I'm using Windows Forms to start a System.Timers.Timer to fire an event every 3 seconds. When I close the form the process keeps firing, and that's fine. The problem happens when I reopen the form to stop the timer on click of a button

btnSendOff_Click
.

System.Timers.Timer sendTimer = new System.Timers.Timer();
sendTimer.Elapsed += new ElapsedEventHandler(sendProcessTimerEvent);
sendTimer.Interval = 3000;

private void sendProcessTimerEvent(object sender, EventArgs e)
{
MessageBox.Show("Send 3 sec");
}

private void btnSendOn_Click(object sender, EventArgs e)
{
sendTimer.Start();
}

private void btnSendOff_Click(object sender, EventArgs e)
{
sendTimer.Stop();
}


There will be more asynchronous timers on this form. How can I stop this timer when I reopen the form?

Answer

The form should not be creating a new timer every time you create a new instance of the form if it needs to keep running after the form closes. The way you have declared the timer, it will create another one each time the form is created. You should put the timer on a different form or declare it in some global module and only make the form activate or deactivate the timer. If the timer needs to keep running when the form is closed, the form should not be the one owning or creating the timer. If the timer doesn't need to keep running when the form is closed, then you should be using a Forms.Timer instead of a System.Timer.

Edit: Add Sample Code

static class Program
{
    public static System.Timers.Timer sendTimer;
    public static System.Text.StringBuilder accumulatedText;

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        sendTimer = new System.Timers.Timer();
        accumulatedText = new System.Text.StringBuilder("Started at " + DateTime.Now.ToLongTimeString() + Environment.NewLine);
        sendTimer.Interval = 3000;
        sendTimer.Elapsed += new System.Timers.ElapsedEventHandler(sendProcessTimerEvent);
        Application.Run(new MainForm());
    }

    static void sendProcessTimerEvent(object sender, System.Timers.ElapsedEventArgs e)
    {
        accumulatedText.AppendLine("Pinged at " + DateTime.Now.ToLongTimeString());
    }
}

class MainForm : Form
{
    ToolStrip mainToolStrip = new ToolStrip();
    public MainForm()
    {
        mainToolStrip.Items.Add("Log Control").Click += new EventHandler(MainForm_Click);
        Controls.Add(mainToolStrip);
    }

    void MainForm_Click(object sender, EventArgs e)
    {
        Form1 frm = new Form1();
        frm.ShowDialog();
    }
}

class Form1 : Form
{
    private Button button1 = new Button();
    private TextBox text1 = new TextBox();
    public Form1()
    {
        button1.Dock = DockStyle.Bottom;
        button1.Text = Program.sendTimer.Enabled ? "Stop": "Start";
        button1.Click += new EventHandler(button1_Click);
        text1 = new TextBox();
        text1.Dock = DockStyle.Fill;
        text1.Multiline= true;
        text1.ScrollBars = ScrollBars.Vertical;
        text1.Text = Program.accumulatedText.ToString();
        Controls.AddRange(new Control[] {button1, text1});
    }

    void button1_Click(object sender, EventArgs e)
    {
        Program.sendTimer.Enabled = !Program.sendTimer.Enabled;
        button1.Text = Program.sendTimer.Enabled ? "Stop" : "Start";
    }
}