Isaac Pounder
Isaac Pounder

Reputation: 187

Why is my System.Timers.Timer event not firing in C#

System.Timers.Timer timer = new System.Timers.Timer();

private void button1_Click(object sender, EventArgs e)
{
    timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
    timer.Interval = 2000;

    timer.Enabled = true;
    timer.Start();
}

private void timer_Elapsed(object myobject, System.Timers.ElapsedEventArgs e)
{
    Say("Time hit" + DateTime.Now.ToString());
}

what am i missing?

EDIT:

Tried to add:

timer.AutoReset = true;

For those curious Say Method is:

private void Say(string s)
        {

            try
            {
                txtSay.AppendText(s + "\r\n");
            }
            catch
            {
            }
        }

The say method doesn't have a problem in there. Works with everything else.

Upvotes: 5

Views: 16666

Answers (6)

Scientist42
Scientist42

Reputation: 77

In C++/CLI (managed C++ using.NET - it is really closed to C#) you should set object to synchronize by this timer.

It could look like this: +-

timer->SynchronizingObject = txtSay;

in C# probably: with "." instead of "->"

See this artice

Upvotes: 0

Henk Holterman
Henk Holterman

Reputation: 273274

Because

  1. your Timers.Timer does not set a SyncObject
  2. Therefore your event fires on another thread
  3. Setting the Text property raises a cross-threading Exception
  4. And then you swallow that exception without any trace

    private void Say(string s)
    {
        try
        {
            txtSay.AppendText(s + "\r\n");
        }
        catch  // empty catch-block: the real fundamental problem
        {
        }
    }
    

So the Timer event does fire but it produces an error that remains hidden.

The short, practical solution would be to use a Windows.Timer for a GUI related timer.

Upvotes: 5

Ade Stringer
Ade Stringer

Reputation: 2661

As Reniuz says, you're likely to be getting an exception because you're trying to update the UI from a different thread. The Timer class runs on a separate thread to prevent it from interfering with the responsiveness of your application.

This is an excellent example of why try { /* something */ } catch {} is a bad idea - you've totally hidden the error from yourself by writing this. If you hadn't written that, you'd probably have been able to figure out that you need to invoke the UI update on the correct thread from the exception message.

Upvotes: 0

chaosr
chaosr

Reputation: 494

You needn't set the EventHandler in the Click Method. Set it e.g. in the constructor of your class and it will work.

Leave the Start() Method in the click function:

private void button1_Click(object sender, EventArgs e)
{
    timer.Start();
}

Upvotes: 0

Renatas M.
Renatas M.

Reputation: 11820

I think you didint mentioned that you getting cross thread exception.. try to change code like that:

Invoke(new Action(()=>Say("Time hit" + DateTime.Now.ToString())));

Upvotes: 5

maka
maka

Reputation: 566

This might not be right, but going by the MSDN example, you shouldn't need to call t.Start(), t.Enable should start it. Since you start it by doing t.Enabled and t.Start, there might be some conflict with the AutoRest property.

I would also make sure the Say method works like it should by adding a break point or something similar. I have no clue what you are calling AppendText on in this case.

A little bit of guess work.

Upvotes: 0

Related Questions