Andrew Hales
Andrew Hales

Reputation: 127

c# WinForms reusable timer duplicating eventhandler

I'm trying to understand the timer class and the event handling that is associated to it. I have an application that will need to call an event at a specific time dependant on the data pulled from the database. Naturally scheduled tasks is not suitable for this.

Here's the code that I am trying to understand

        private Timer setTimer = new Timer();

    public Form1()
    {
        InitializeComponent();
        TimedProcess(null, null);

    }

    private void SetTimer(DateTime dtNextStop)
    {
        TimeSpan span = dtNextStop - DateTime.Now;
        int ms = (int)span.TotalMilliseconds;
        setTimer.Interval = ms;
        setTimer.Tick += new EventHandler(TimedProcess);
        setTimer.Start();
    }


    public void TimedProcess(Object sender, EventArgs e)
    {
        setTimer.Stop();
        setTimer.Dispose();
        txtLog.Text = txtLog.Text = "Tick " + DateTime.Now.ToString("HH:mm:ss") + "\r\n" + txtLog.Text;
        SetTimer(DateTime.Now.AddSeconds(4));
    }

I was trying to be smart (haha failed at that one) by declaring the timer globally to save on resources and reuse this for the next time section. I noticed that the application was leaking memory so I created a textbox to output the ticks. This produced some strange results. I'm obviously doing something wrong, any help would be greatly appreciated.

Tick 18:44:50
Tick 18:44:50
Tick 18:44:50
Tick 18:44:50
Tick 18:44:50
Tick 18:44:50
Tick 18:44:50
Tick 18:44:50
Tick 18:44:46
Tick 18:44:46
Tick 18:44:46
Tick 18:44:46
Tick 18:44:42
Tick 18:44:42
Tick 18:44:38
Tick 18:44:34

Upvotes: 0

Views: 308

Answers (2)

adv12
adv12

Reputation: 8551

There are a lot of things wrong with your code; I'm not sure which is causing what you see as "the problem."

For starters, you're only ever using one Timer object, but you are apparently Dispose()-ing it with every call to TimedProcess. I strongly recommend not continuing to use an object you've disposed (or, to put it another way, not disposing an object you intend to keep using).

Next, you're registering for the setTimer.Tick event every time SetTimer is called. That's probably why you're seeing more lines for each firing of the Tick event.

Is setTimer a System.Timers.Timer or a System.Windows.Forms.Timer? If the latter, it needs to be associated with a control, and if the former, you need to Invoke changes you make to the GUI when the timer is fired, as it'll be fired on a background thread.

Upvotes: 1

Shago
Shago

Reputation: 605

The problem is that SetTimer is attaching the event handler again, you only need to do that once.

Upvotes: 2

Related Questions