当多个线程试图在Winforms中同时使用Invoke更新表单控件时会发生什么情况
本文关键字:表单 更新 Invoke 控件 什么情况 线程 Winforms | 更新日期: 2023-09-27 18:20:00
当多个线程试图使用Invoke调用一个表单方法时,会发生什么?Invoke在Winforms中同时更新表单控件?
static thCount = 0;
private void button1_Click(object sender, EventArgs e)
{
System.Threading.Thread t1 = new System.Threading.Thread(start);
System.Threading.Thread t2 = new System.Threading.Thread(start);
t1.Start();
t2.Start();
}
private void start()
{
System.Threading.Thread.Sleep(300);
Invoke(new MethodInvoker(guiUpdate));
}
private void guiUpdate()
{
this.label1.Text = "Updated.." + (thCount++);
this.label1.Update();
}
private void Form1_Load(object sender, EventArgs e)
{
this.label1.Text = System.Threading.Thread.CurrentThread.Name;
}
试试吧!:)您会发现,它们都不能从后台线程更新UI,而是需要使用Control.BeginInvoke
来调用UI线程上的工作,在这种情况下,它们将按照调用BeginInvoke
的顺序执行。
任何一个线程都无法更新GUI。
如果不选中"InvokeRequired",则可能会出现跨线程异常。
如果仍然希望这些线程访问相同的方法,可以使用互斥概念。
你可以在这里找到更多关于互斥的信息。
这个关于堆栈溢出的问题也详细解释了互斥。
Invoke
阻塞,直到线程完成执行更新方法。
然而,这实际上只是给GUI线程的一条消息,它会等待,直到完成为止。由于GUI线程一次只能执行一个方法,因此没有真正的同时执行。没有什么不好的事情发生,但行为可能取决于执行的顺序。
然而,执行的顺序取决于哪个线程完成了一些有保证的原子(锁)操作。