我最近开始学习C#,我试图在计时器的帮助下每分钟重复一次方法。该方法更改标签的值。但是,我收到以下错误:
$ exception {“跨线程操作无效:控制'label1' 从创建它的线程以外的线程访问 on。“} System.Exception {System.InvalidOperationException}
我试过寻找解决方案,每个线程都让我感到困惑。我不仅需要正确的代码,还需要解释,因为我想学习在定时器和线程的帮助下操作UI。
以下是我的代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Timers;
using System.Windows.Forms;
namespace Winforms_Timer_and_Thread
{
public partial class Form1 : Form
{
System.Timers.Timer myTimer = new System.Timers.Timer();
public Form1()
{
myTimer.Enabled = true;
InitializeComponent();
}
public void startMethod(object senter, ElapsedEventArgs e)
{
int cntr = 0;
cntr++;
label1.Text = "Executed: " + cntr.ToString();
}
private void button1_Click(object sender, EventArgs e)
{
label1.Text = "Started!";
myTimer.Enabled = true;
myTimer.Interval=(1*60*1000);
myTimer.Elapsed += new System.Timers.ElapsedEventHandler(startMethod);
}
}
}
答案 0 :(得分:2)
如果您更改为使用System.Windows.Forms.Timer
,则您不会遇到此问题,因为它在同一个UI线程中执行。
您只需要更改:
System.Timers.Timer
到System.Windows.Forms.Timer
Elapsed
订阅到Tick
ElapsedEventArgs e
变为EventArgs e
您也只需要订阅一次事件,而不是每次都启用计时器,因此请将其移至Form_Load
事件以及Interval
分配(尽管可以更改)任何时候)。
您也可能希望将计数器变量存储在StartMethod
之外,因此每次执行时它都会递增,然后在每次启动计时器时将其重置为零:
public partial class Form1 : Form
{
readonly System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();
private int tickCounter;
public Form1()
{
InitializeComponent();
myTimer.Interval = (int)TimeSpan.FromMinutes(1).TotalMilliseconds;
myTimer.Tick += StartMethod;
}
private void StartMethod(object sender, EventArgs e)
{
tickCounter++;
label1.Text = "Number of executions: " + tickCounter;
}
private void button1_Click(object sender, EventArgs e)
{
tickCounter = 0;
label1.Text = "Started!";
myTimer.Enabled = true;
}
}