我正在尝试创建一个触发方法的计时器,每分钟更新一个充当时钟的文本框,以便在现实生活中经过的每一分钟都是游戏中的一小时。这是我到目前为止的代码:
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
但我继续在上面指定的行中收到此错误:
“System.Windows.Forms.dll中发生了'System.InvalidOperationException'类型的异常,但未在用户代码中处理
附加信息:跨线程操作无效:控制从创建它的线程以外的线程访问的'timeBox'。“
如果有人能帮助我,那就太棒了
答案 0 :(得分:2)
问题来自于事件是在与运行用户界面(UI)不同的线程上触发的。 UI的所有控件元素都属于UI线程,系统不允许您从另一个线程中操作它们。
看起来您正在使用WinForms,因此我建议您使用命名空间System.Windows.Forms
提供的Timer。它在UI-Thread上运行,因此该异常将消失,无需使用Invoke
:
System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
此处的活动名为Tick,而不是Elapsed
:
timer1.Tick += UpdateTime;
您的方法会有所不同:
private void UpdateTime(object sender, EventArgs e)
{
此计时器也将自动重启,直到您在计时器上调用Stop()