相当令人沮丧,因为这似乎有很好的记录和事实,我之前完成了这一事实,但不能重复同样的成功。对不起,我会尝试清楚地说明这一点。
Visual Studio,C#表单,一个主表单包含文本字段以及其他小部件。
我们有一个概念,即我们正在“运行”,因此收集数据。
目前,我启动了一秒计时器,以便我可以将模拟数据更新到某些字段中。最终,一秒计时器将获取更快速的数据,并且每秒仅更新一次到屏幕,这就是对应用程序的请求,我们现在以我们收到的速率更新,这有点超过70赫兹,他们不想要就这样。此外,还将计算一些其他统计数据,这些数据应该是字段更新。因此很简单我只想生成随机数据并以1 Hz的速率更新这些字段。然后从那时开始扩展。
定时器的定义和管理:(这都在同一类MainScreen中)
System.Timers.Timer oneSecondTimer;
public UInt32 run_time = 0;
public int motion = 5;
private void InitializeTimers()
{
this.oneSecondTimer = new System.Timers.Timer(1000);
this.oneSecondTimer.Elapsed += new System.Timers.ElapsedEventHandler(oneSecondTimer_elapsed);
}
public void start_one_second_timer()
{
run_time = 0;
oneSecondTimer.Enabled = true;
}
public void stop_one_second_timer()
{
oneSecondTimer.Enabled = false;
run_time = 0;
}
Random mot = new Random();
private void oneSecondTimer_elapsed(object source, System.Timers.ElapsedEventArgs e)
{
run_time++;
motion = mot.Next(1, 10);
this.oneSecondThread = new Thread(new ThreadStart(this.UpdateTextFields));
this.oneSecondThread.Start();
}
private void UpdateTextFields()
{
this.motionDisplay.Text = this.motion.ToString();
}
motionDisplay只是我主要表单中的一个文本框。我得到了无效操作异常,指向我如何进行线程安全调用的帮助。我也试过backgroundworker并得到相同的结果。详细信息是可以从创建它的线程以外的线程访问motionDisplay。
所以寻找一些关于我的错误在哪里的建议。
最诚挚的问候。我继续对此进行迭代,如果找到解决方案,我会更新。
答案 0 :(得分:1)
试试这个
private void UpdateTextFields()
{
this.BeginInvoke(new EventHandler((s,e)=>{
this.motionDisplay.Text = this.motion.ToString();
}));
}
这将正确地回复主线程。
WinForm开发的一点是所有控件都不是线程安全的。即使从另一个线程获取诸如.Text之类的属性也可能导致这些类型的错误发生。让它更令人沮丧的是,有时它会在运行时工作,你不会得到例外,有时你也会。
答案 1 :(得分:1)
使用System.Forms.Timer
而不是System.Timers.Timer
。它将在UI线程中触发它已经过去的事件。
不要创建新线程来更新UI;只需在已过时的事件处理程序中进行更新。
答案 2 :(得分:1)
我就是这样做的:
private delegate void UpdateMotionDisplayCallback(string text);
private void UpdateMotionDisplay(string text) {
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.motionDisplay.InvokeRequired) {
UpdateMotionDisplayCallback d = new UpdateMotionDisplayCallback(UpdateMotionDisplay);
this.Invoke(d, new object[] { text });
} else {
this.motionDisplay.Text = text;
}
}
如果要更新motionDisplay中的文本,请调用:
UpdateMotionDisplay(this.motion.ToString())