1

我对线程非常陌生,因此不太确定这是否是一种竞争条件。我正在使用 C# 的 SerialPort 类从串行设备查询数据。我通过互联网阅读的理解是,当触发数据接收事件时,此类会产生一个单独的线程。当程序不允许我在事件方法中设置文本框的值时,这似乎得到了证实,因为控件只能在创建它们的线程中设置。我的问题是我认为设置文本框内容的方式存在竞争条件。

使用这种方法

private void btnWidth_Click(object sender, EventArgs e)
{
    mySerialManager.ClearErrorQueue();
    mySerialManager.WriteLine();
    Thread.Sleep(1000);

    if (mySerialManager.HasErrors())
    {
        MessageBox.Show("There was an Error Accessing the Serial Device:\n\r" + PrintAllErrors(mySerialManager), "Serial Device Error");
        return;
    }

    btnSubmit.Enabled = true;
    btnSubmit.Select();
    txtMeasWidth.Text = myRecievedData.Substring(0, myRecievedData.Length - 1).Trim();
}

我将数据命令写入串行设备,然后设置文本框内容。事件处理程序在触发后设置 myRecievedData 字符串的值。我的问题是如何确保事件已被触发并在写入文本框之前设置了此字符串的值。我在方法的底部做了这个作为一种快速修复,但我想确保如果这是一个竞争条件,它会得到处理。

对不起,这太啰嗦了。在此先感谢您的帮助!

4

2 回答 2

2

你是正确的,有一个竞争条件。您可以使用Invoke方法从 SerialPort 的事件处理程序中安全地更新文本框:

txtMeasWidth.Invoke((Action)delegate { txtMeasWidth.Text = myRecievedData; });
于 2012-06-21T19:19:17.787 回答
1

是的,您在这里创建了一个竞争条件。
但它很容易修复。

在您ComPortDataReceivedEventHandler只需调用一个方法,该方法将使用适当的文本设置您的文本框

例如:

form.Invoke(new MethodInvoker(delegate() {textMeasWidth.Text = myreceivedData}))
于 2012-06-21T19:24:45.927 回答