使用文本框调用c#

eat*_*mup 4 c# multithreading serial-port event-handling visual-studio-2010

我的程序的一部分使用事件处理程序来接收我的串行端口的数据.这个想法是当收到数据时,接收到的文本然后被添加到文本框(rx).我不习惯这个问题,但有些事情发生了变化,我无法弄清楚是什么.所以现在我正在重新审视这个问题的处理方式.

在winform形式加载期间,我做的最后一件事就是

if (!serialPort1.IsOpen)
{
     serialPort1.Open();
     serialPort1.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
}
Run Code Online (Sandbox Code Playgroud)

然后我有事件处理程序

private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
     string indata1 = serialPort1.ReadExisting();
    // rx.Text = " "; accidentally posted this. it was from trial and error.  
     rx.AppendText(Environment.NewLine + indata1);
}
Run Code Online (Sandbox Code Playgroud)

当我运行程序时它停在那里rx.AppendText(Environment.NewLine + indata1);并给出错误

invalidoperationexception未处理:控制"从创建它的线程以外的线程访问.

从我能够阅读的建议我需要使用invokeBeginInvoke.

我之前没有遇到任何问题,所以现在我无法理解为什么这是一个问题.从我一直在阅读的调用我只是不明白它.

有人可以帮我理解如何在我的情况下使用调用实例吗?或者可能告诉我另一种附加文本框的方法?

Tud*_*dor 5

GUI应用程序中的更新应仅在GUI线程上完成.尝试直接更新GUI组件的另一个线程将导致您描述的错误或看似随机的行为.

Invoke&friends 的作用是使辅助线程能够安全地将GUI更新转发到GUI线程,然后GUI线程将从队列中处理它们.

在你的情况下(假设WinForms在这里):

rx.BeginInvoke(
      (Action)(() =>
      {
          rx.AppendText(Environment.NewLine + indata1);
      }));
Run Code Online (Sandbox Code Playgroud)

BeginInvoke是异步的,因此调用它的线程不会等待在继续之前处理实际更新,Invoke而是同步的.


hmq*_*esy 5

通常,您在调试模式下运行时会看到异常,如果您在发布模式下运行应用程序,则不太可能看到异常。

但是,正如您所阅读的那样,最好使用 invoke。像这样的东西:

    private delegate void RefreshTextBox();

    private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) {
        //this event is raised in an event separate from UI thread, 
        //so InvokeRequired must be checked and Invoke called to update UI controls. 
        if (this.InvokeRequired) {
            RefreshTextBox d = new RefreshTextBox(RefreshTextBoxResults);
            Invoke(d);
        } else {
            RefreshTextBoxResults();
        }
    }

    private void RefreshTextBoxResults() {
        string indata1 = serialPort1.ReadExisting();
        rx.Text = " ";
        rx.AppendText(Environment.NewLine + indata1);
    }
Run Code Online (Sandbox Code Playgroud)

第一次看到这个 invoke 东西时,几乎无法理解,但仔细看看并给它一些时间,它会有意义。承诺。:)