Reputation: 17
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
Upvotes: 1
Views: 206
Reputation: 23732
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
Upvotes: 2