我正在研究连接到步进电机的串行端口的代码。我通过textBox2向步进电机发送了一条命令,并试图从命令中将返回数据读入textBox3。我能够建立连接,发送命令并接收数据。但是在我的GUI用返回的串行数据填充textBox3后,它冻结了。

我相信代码被卡在try loop中,但是我不知道如何突破。这是我的代码:

private void button3_Click(object sender, EventArgs e)
{
    if (isConnectedMotor)
    {
        string command = textBox2.Text;
        portMotor.Write(command + "\r\n");
        portMotor.DiscardInBuffer();

        while (true)
        {
            try
            {
                string return_data = portMotor.ReadLine();
                textBox3.AppendText(return_data);
                textBox3.AppendText(Environment.NewLine);
            }
            catch(TimeoutException)
            {
                break;
            }
        }
    }
}


数据接收代码:

private void connectToMotor()
{
    isConnectedMotor = true;
    string selectedPort = comboBox2.GetItemText(comboBox2.SelectedItem);
    portMotor = new SerialPort(selectedPort, 9600, Parity.None, 8, StopBits.One);
    portMotor.RtsEnable = true;
    portMotor.DtrEnable = true;
    portMotor.Open();
    portMotor.DiscardInBuffer();
    portMotor.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
    button4.Text = "Disconnect";
    enableControlsMotor();
}

private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
    SerialPort sp = (SerialPort)sender;
    string indata = sp.ReadExisting();
    textBox3.AppendText(indata);
    textBox3.AppendText(Environment.NewLine);
}


我收到一个错误消息:


  非静态字段,方法或属性“ Form1.textBox3”需要对象引用


调用代码:

私有void DataReceivedHandler(对象发送者,SerialDataReceivedEventArgs e)
        {

        portMotor.DiscardInBuffer();
        incoming_data = portMotor.ReadExisting();
        this.Invoke(new EventHandler(displayText));
    }

    private void displayText(object o, EventArgs e)
    {
        textBox3.Text += incoming_data;
    }

最佳答案

与其循环读取数据,不如使用DataReceived事件来异步获取传入的字节。

请参见documentation and example
另请参阅this question进行故障排除。

附言这是避免锁定UI的代码示例。

private void ReceivedHandler(object sender, SerialDataReceivedEventArgs e) {
    var incoming_data = portMotor.ReadExisting();

    // this is executing on a separate thread - so throw it on the UI thread
    Invoke(new Action(() => {
        textBox3.Text += incoming_data;
    }));
}

10-07 13:22
查看更多