窗口究竟发生了什么形成线程

本文关键字:线程 什么 究竟 发生了 窗口 | 更新日期: 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 线程上运行,因此跨线程问题已解决。

诀窍是委托不会直接在非 UI 调用线程上调用。使用 Windows 消息,执行委托的指令将传递到 UI 线程,然后 UI 线程执行委托以响应消息。"Control.Invoke"使用Windows [SendMessage][1]Control.BeginInvoke使用[PostMessage][2] Win32 API来促进消息传递。

UI 控件不能从创建它的主线程/线程以外的任何线程更新/更改。

在您的情况下,检查 InvokeRequired 会检查希望更改控件的线程是否是创建线程,如果不是,则将调用传递回主线程/创建者。

查看如何:对 Windows 窗体控件进行线程安全调用

如果使用多线程来提高 Windows 的性能 表单应用程序,您必须确保调用您的 以线程安全的方式进行控件。

对 Windows 窗体控件的访问本质上不是线程安全的。如果你 有两个或多个线程操作控件的状态,它是 可能强制控件进入不一致状态。其他 可能出现与线程相关的错误,例如竞争条件和 僵局。确保访问控件非常重要 以线程安全的方式执行。

在不使用 Invoke 方法的情况下,从创建控件的线程以外的线程调用控件是不安全的。