跨线程操作
本文关键字:操作 线程 | 更新日期: 2023-09-27 17:57:35
有人能告诉我if和else语句在这个函数中是如何关联的吗。我正在显示从另一个线程到GUI线程的文本。执行的顺序或方式是什么。其他陈述有必要吗?
delegate void SetTextCallback(string text);
private void SetText(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.textBox7.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.textBox7.Text = text;
}
}
- 另一个线程调用SetText
- 由于它不是创建表单的线程,因此它需要
Invoke
this.Invoke
再次调用具有给定参数的SetText。还要检查这个- 现在从UI线程调用SetText,不需要调用
- 在
else
块中,我们确信文本被安全地设置为线程
InvokeRequired
用于检查语句是在主UI线程中执行还是在UI线程以外的其他线程中执行。
如果语句是在UI线程以外的其他线程中执行的,则Invoke
用于不引起任何CrossThread
异常。
else
是绝对必要的。
此代码所做的是允许您从任何线程安全地调用SetText
。如果从UI线程(if
块)以外的线程调用它,它会透明地将调用转发到UI线程(else
块),后者是唯一可以访问控件以读取或设置其文本的线程。
如果不在UI线程上执行,盲目地执行this.textBox7.Text
将导致异常。
添加到其他答案中,这是一种常见的模式(尤其是在被调用方法包含大量逻辑的场景中)-如果InvokeRequired
返回true,则从UI线程回调到同一方法:
private void SetText(string text)
{
if (InvokeRequired)
BeginInvoke(new Action<string>((t) => SetText(text)));
else
textBox7.Text = text;
}
这样,您就不必在if
和else
中重复您的逻辑。