1

I am trying to make a timer that triggers a method, that updates a text box that acts as a clock, every minute so that each minute that passes in real life is an hour in game. Here is the code I have so far:

public partial class Terminal : Form
{
    static int time;
    System.Timers.Timer timer1 = new System.Timers.Timer();

    private void Terminal_Load(object sender, EventArgs e)
    {
        time = 0;

        timer1.Elapsed += new ElapsedEventHandler(UpdateTime);
        timer1.Interval = 1000;
        timer1.AutoReset = true;

        GoToPage(Pages.Tasks);
        UpdateClock(time);
        timer1.Start();
    } //private void Terminal_Load(object sender, EventArgs e)

    private void UpdateTime(object source, ElapsedEventArgs eea)
    {
        if (time < 6) //the clock is not supposed to go any further than 6 am
            time++;
        UpdateClock(time);
    } //private static Task UpdateTime(int t)

    private void UpdateClock(int t)
    {
        if (time == 0)
        {
            timeBox.Text = "12 AM";
        } //if
        else if (time > 0 && time <= 6)
        {
            timeBox.Text = time + " AM"; //error appears here each time the timer elapses
        } //else if
    } //private void UpdateClock()
} //public partial class Terminal : Form

But I keep on getting this error at the above specified line:

"An exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll but was not handled in user code

Additional information: Cross-thread operation not valid: Control 'timeBox' accessed from a thread other than the thread it was created on."

If anyone could help me out that would be great

Community
  • 1
  • 1
DodgeCoder
  • 17
  • 7
  • 2
    Use BeginInvoke – Mikko Viitala Dec 12 '17 at 09:10
  • You have to set 'timeBox.Text' in the GUI Thread. As explained here: https://stackoverflow.com/questions/6268250/begininvoke-gui-and-thread – richej Dec 12 '17 at 09:15
  • 1
    Possible duplicate of [Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on](https://stackoverflow.com/questions/142003/cross-thread-operation-not-valid-control-accessed-from-a-thread-other-than-the) – Equalsk Dec 12 '17 at 09:17

1 Answers1

2

You problem comes from the point that the event is fired on a different thread than the user interface (UI) is running on. All the control elements of the UI belong to the UI-thread and the system will not allow you to manipulate them from another thread.

It looks like you are working in WinForms, so I would suggest to take the Timer supplied by the namespace System.Windows.Forms. It runs on the UI-Thread so this exception will disappear and no need to use Invoke:

System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();

the event is here called Tick instead of Elapsed:

timer1.Tick += UpdateTime;

Your method will look a little different:

private void UpdateTime(object sender, EventArgs e)
{

this timer will also restart automatically until you call Stop() on the timer

Mong Zhu
  • 23,309
  • 10
  • 44
  • 76