源文链接:https://blog.youkuaiyun.com/TheBestAge/article/details/85331742
线程间操作无效:从不是创建控件“textBox1”的线程访问它
问题代码:
public void test(object source, ElapsedEventArgs e)
{
//实例化BLL层对应界面
QRcodeBLL qucode = new QRcodeBLL();
//501考场剩余座位
StudentBindPaperTypeEntity StudentBindPaperType = new StudentBindPaperTypeEntity();
StudentBindPaperType.IP = textBox2.Text.Trim();
DataTable dt = qucode.SelectByIP(StudentBindPaperType);
//511考场剩余座位
StudentBindPaperTypeEntity StudentBindPaperType1 = new StudentBindPaperTypeEntity();
StudentBindPaperType.IP = textBox3.Text.Trim();
DataTable table = qucode.SelectByIP(StudentBindPaperType);
textBox1.Text = "501剩余座位数:" + (200 - Convert.ToInt32(dt.Rows[0][0])) + Environment.NewLine
+ "511剩余座位数:" + (200 - Convert.ToInt32(table.Rows[0][0]));
}
问题解决:
1.在窗体的构造函数中添加:
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
1
2.通过代理来解决:
private delegate void SetTextCallback(string text);
//在给textBox1.text赋值的地方调用以下方法即可
private void SetText(string text)
{
// InvokeRequired需要比较调用线程ID和创建线程ID
// 如果它们不相同则返回true
if (this.textBox1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.textBox1.Text = text;
}
}
问题产生原因:
NET2.0以后拒绝多线程访问控件,避免控件造成死锁。
在UI线程创建的子线程操作UI控件,访问windows窗台控件在本质上不是线程安全的。如果有两个或多个线程操作某一控件的状态,则可能会迫使该控件进入一种不一致的状态。还可能出现其他与线程相关的bug,包括争用情况和死锁。确保以线程安全方式访问控件非常重要。
在调试器中运行应用程序时,如果创建某控件的线程之外的其他线程试图调用该控件,则调试器会引发一个InvalidOperationException异常,并提示消息:“从不是创建控件的线程访问它”。
原文链接:https://blog.youkuaiyun.com/TheBestAge/article/details/85331742