修复C#race条件

修复C#race条件,c#,visual-studio-2008,thread-safety,serial-port,C#,Visual Studio 2008,Thread Safety,Serial Port,我对线程非常陌生,因此不太确定这是否是一种竞争条件。我正在使用C#的SerialPort类从串行设备查询数据。通过阅读internet,我的理解是,当触发接收到的数据事件时,这个类生成一个单独的线程。当程序不允许我在事件方法中设置文本框的值时,这似乎得到了证实,因为控件只能在创建它们的线程中设置。我的问题是,我认为在设置文本框内容的方式中存在竞争条件 使用这种方法 private void btnWidth_Click(object sender, EventArgs e) { mySe

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

使用这种方法

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


对不起,这太冗长了。提前感谢您的帮助

你说得对,这是一个竞赛条件。您可以使用该方法从SerialPort的事件处理程序安全地更新文本框:

txtMeasWidth.Invoke((Action)delegate { txtMeasWidth.Text = myRecievedData; });

是的,您正在这里创建比赛条件。
但它很容易修复。

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

例如:

form.Invoke(new MethodInvoker(delegate() {textMeasWidth.Text = myreceivedData}))

为什么会被否决?这是一个明确的问题。我尝试过使用invoke,但实际上它什么都没做。是否存在与调用相关的任何问题?我看到的一个区别是,我使用的是表单调用,而不是文本框。也许这就是问题所在?不,在表单上调用Invoke也应该起作用。当您尝试它时,您传递给调用的委托从未真正被调用过?事实上,它完全忽略了这一行,如果我尝试单步执行代码,调试器将冻结在这一行。实际上,我让它使用Invoke。我在另一个答案中使用了代码,因为VisualStudio对您的建议有一些问题。我对两个答案都投了更高的票,因为它们几乎是一样的。所以这很奇怪。在我正在做的这个项目中,它不允许我将角色转换为动作,它只能作为泛型类型(即动作)使用。但在我的测试项目中,它会让我做那个角色。这显然是我这边的事。