0

I am trying to display a basic clock from system time. I don't understand why this is crashing. I am hoping someone can help me to understand my error here.

At this point the form is just a label with short time displayed. I am trying to just make it update the label text on its own.

The label shows the time just fine on load. But when the timer_elapsed occurs the error is thrown

private void Form1_Load(object sender, EventArgs e)
{
    lblClock.Text = DateTime.Now.ToShortTimeString();
    timer = new System.Timers.Timer();
    timer.Interval = 1000;
    timer.Elapsed += timer_Elapsed;
    timer.Enabled = true;
    timer.Start();
}


void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    lblClock.Text = DateTime.Now.ToShortTimeString();
}

The error is InvalidOperationException was unhandled by user code

Why does this work on load but not on update?


This was marked as a duplicate, but I have to disagree. Based on the linked duplicate thread the questions aren't the same. This question refers to why the exact same method works on load but not on call. The other thread is simply asking in general how to update a UI.

eatumup
  • 525
  • 12
  • 26
  • 2
    Use `System.Windows.Forms.Timer` instead and handle its `Tick` event. Or use `Invoke` and pass a delegate to update the UI thread. – Reza Aghaei Mar 02 '17 at 00:31
  • @RezaAghaei Thank you for the answer and the help! However, I don't see how this is a duplicate of the other post. Im not asking how to update the UI, just trying to understand why the method works on load but not in run. Based on that OP question I wouldn't see the connection there on search. – eatumup Mar 02 '17 at 01:20
  • 1
    The problem is basically updating the UI from another thread and the linked post shows how to update UI from another thread. Also the first comment and the posted answer guide you to use `System.Windows.Forms.Timer` instead of `System.Timers.Timer` :) – Reza Aghaei Mar 02 '17 at 01:32

1 Answers1

1

It's crashing because you are using System.Timers.Timer and object of that class cannot update your UI elements. Use System.Windows.Timer and it should be fine.

Please not that you will need to use the Tick event because there is no Elapsed event.

Timer timer;
    public Form1()
    {
        InitializeComponent();
        timer = new Timer();
        timer.Enabled = true;
        timer.Interval = 1000;
        timer.Tick += Timer_Tick;
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        lblClock.Text = DateTime.Now.ToShortTimeString();
        timer.Start();
    }

    private void Timer_Tick(object sender, EventArgs e)
    {
        lblClock.Text = DateTime.Now.ToShortTimeString();
    }
}
Mr Tangjai
  • 153
  • 2
  • 9
CodingYoshi
  • 25,467
  • 4
  • 62
  • 64
  • Thank you very much for your response, I did not realize there were two different timers, let alone a difference between the two. I thought what i was doing was just implementing the same GUI timer without the drag and drop. Thank you for pointing out the difference. – eatumup Mar 02 '17 at 01:29
  • 2
    In fact there are multiple times in .NET Framework with different goals: [`System.Timers.Timer`](https://msdn.microsoft.com/en-us/library/system.timers.timer(v=vs.110).aspx), [`System.Threading.Timer`](https://msdn.microsoft.com/en-us/library/system.threading.timer(v=vs.110).aspx), [`System.Windows.Forms.Timer`](https://msdn.microsoft.com/en-us/library/system.windows.forms.timer(v=vs.110).aspx), [`System.Web.UI.Timer`](https://msdn.microsoft.com/en-us/library/system.web.ui.timer(v=vs.110).aspx). – Reza Aghaei Mar 02 '17 at 01:35