窗口究竟发生了什么形成线程
本文关键字:线程 什么 究竟 发生了 窗口 | 更新日期: 2023-09-27 18:32:00
在异步 OnMsgRecieved 调用中,如果我直接将值分配给控件,则它不起作用。然后我知道这是由于线程不安全,我得到了以下代码来解决问题。现在它正在工作。但我不确定它实际上做了什么。谁能让我完全理解它?代码是:-
public void listener_OnMsgRecieved(string aResponse)
{
ShowResponseMessage(aResponse);
}
public void ShowResponseMessage(string aResponse)
{
// 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.listBox.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(ShowResponseMessage);
this.Invoke(d, new object[] { aResponse });
}
else
{
this.listBox.Items.Add(aResponse);
label.Text = "Response received from Server :";
}
}
当在与 UI 不同的线程上调用 ShowResponseMessage 时,InvokeRequired
将返回 true
,然后您使用 Control.Invoke
将消息发送到 Windows 消息队列。
中运行的 UI 消息泵将拉取消息并将其传递到目标控件,然后目标控件看到这是一条请求调用委托的消息,并且该委托由控件调用,这现在在 UI 线程上运行,因此跨线程问题已解决。
诀窍是委托不会直接在非 UI 调用线程上调用。使用 Windows 消息,执行委托的指令将传递到 UI 线程,然后 UI 线程执行委托以响应消息。"Control.Invoke"使用Windows [SendMessage][1]
,Control.BeginInvoke
使用[PostMessage][2]
Win32 API来促进消息传递。
UI 控件不能从创建它的主线程/线程以外的任何线程更新/更改。
在您的情况下,检查 InvokeRequired 会检查希望更改控件的线程是否是创建线程,如果不是,则将调用传递回主线程/创建者。
查看如何:对 Windows 窗体控件进行线程安全调用
如果使用多线程来提高 Windows 的性能 表单应用程序,您必须确保调用您的 以线程安全的方式进行控件。
对 Windows 窗体控件的访问本质上不是线程安全的。如果你 有两个或多个线程操作控件的状态,它是 可能强制控件进入不一致状态。其他 可能出现与线程相关的错误,例如竞争条件和 僵局。确保访问控件非常重要 以线程安全的方式执行。
在不使用 Invoke 方法的情况下,从创建控件的线程以外的线程调用控件是不安全的。