【问题标题】:What exactly is happening with windows form threads?windows窗体线程到底发生了什么?
【发布时间】:2012-04-24 05:20:43
【问题描述】:

在异步 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 :";
        }
    }

【问题讨论】:

    标签: c# .net winforms multithreading thread-safety


    【解决方案1】:

    当在不同于 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 来促进消息传递。

    【讨论】:

    • 有什么和同步上下文相关的吗?
    • 谢谢,实用的解释!
    【解决方案2】:

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

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

    看看How to: Make Thread-Safe Calls to Windows Forms Controls

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-12
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多