C#Windows窗体中的线程错误
本文关键字:线程 错误 窗体 C#Windows | 更新日期: 2023-09-27 18:21:17
我得到了这个错误:
"System.InvalidOperationException"类型的未处理异常发生在System.Windows.Forms.dll 中
附加信息:跨线程操作无效:控件从创建的线程以外的线程访问"Redlight"上。
红灯和绿灯是图片盒。基本上,我所希望它能做的就是每秒钟在每张照片之间交替。我在这个网站上搜索了类似的错误,我看到它与"调用"有关,但我甚至不知道那是什么,有人能启发我吗?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
namespace EMCTool
{
public partial class EMCTool_MainForm : Form
{
bool offOn = false;
public EMCTool_MainForm()
{
InitializeComponent();
}
private void EMCTool_MainForm_Load(object sender, EventArgs e)
{
System.Threading.Timer timer = new System.Threading.Timer(new System.Threading.TimerCallback(timerCallback), null, 0, 1000);
}
private void timerCallback(object obj)
{
if (offOn == false)
{
Redlight.Show();
offOn = true;
}
else
{
Greenlight.Show();
offOn = false;
}
}
}
}
当您尝试从任何未创建的线程更新UI元素时,会出现跨线程错误。
Windows窗体中的控件绑定到特定线程,并且不是线程安全的。因此,如果从不同的线程调用控件的方法,则必须使用控件的某个invoke方法将调用封送到适当的线程。此属性可用于确定是否必须调用invoke方法,如果您不知道哪个线程拥有控件,则该方法非常有用。
请参阅此处了解更多
试试这个。这个对我来说很好
if (pictureBoxname.InvokeRequired)
pictureBoxname.Invoke(new MethodInvoker(delegate
{
//access picturebox here
}));
else
{
//access picturebox here
}
在WinForms项目中,最好使用System.Windows.Forms.Timer
,因为它会自动调用UI线程上的Tick
事件:
private System.Windows.Forms.Timer _timer;
private void EMCTool_MainForm_Load(object sender, EventArgs e)
{
_timer = new System.Windows.Forms.Timer { Interval = 1000 };
_timer.Tick += Timer_Tick;
_timer.Start();
}
private void Timer_Tick(object sender, EventArgs e)
{
if (offOn) {
Greenlight.Show();
} else {
Redlight.Show();
}
offOn = !offOn;
}
另一种解决方案是使用具有SynchronizingObject属性的System.Timers.Timer,因此设置此属性,它就会工作:
timer.SynchronizingObject = This
或者使用System.Windows.Forms.Timer,因为它不会引发异常(它会在UI线程上引发Tick事件)。