0

我定义了一个串行端口(C#/.Net),然后为接收到数据分配了一个SerialDataReceivedEventHandler

myPort.DataReceived += new SerialDataReceivedEventHandler (myEventHandler);

但是,每当收到数据时,我需要做很多事情,包括:

  • 将数据保存到我的 SQL 数据库。
  • 在 UI 上更新 RichTextBox
  • 发回响应串行消息

我应该从myEventHandler中运行所有这些函数吗?这是正确的做法吗?问题是,例如,当我尝试从myEventHandler更改RichTextBox时,我收到一条错误消息,指出我正在执行跨线程操作。

更新:

private void myEventHandler (object sender, SerialDataReceivedEventArgs e)
{
    Action myAction = () => rtbMyRichTextBox.Text = InputMessageString;
    if (rtbMyRichTextBox.InvokeRequired)
        rtbMyRichTextBox.Invoke(myAction);
    else
        myAction();

    StoreToSqlDatabase ();

    SerialWriteResponseMessage ();
}
4

1 回答 1

1

您应该在该事件处理程序中或在它调用的方法中执行所有这些操作。

您通过与 UI 线程同步来解决跨线程问题。如果这是一个 Windows 窗体应用程序,您想使用InvokeRequiredInvoke。这些文档链接有很好的例子。

SerialPort.DataReceived的文档说:

从 SerialPort 对象接收数据时,在辅助线程上引发 DataReceived 事件。由于此事件是在辅助线程而不是主线程上引发的,因此尝试修改主线程中的某些元素(例如 UI 元素)可能会引发线程异常。如果需要修改主窗体或控件中的元素,请使用 Invoke 将更改请求发回,这将在适当的线程上完成工作。

代码看起来像:

void myEventHandler(object sender, SerialDataReceivedEventArgs e)
{
    DoSqlUpdate();
    this.Invoke(UpdateUI, data);  // pass whatever data that needs to be updated
    SendResponseMessage();
}
于 2013-07-10T12:33:00.803 回答