Winforms上的串行端口

时间:2018-04-18 05:32:59

标签: c#

我想知道为什么我在使用winform应用程序时没有接收到我的串口,但在控制台应用程序上我使用了相同的代码,它工作正常。

注意:我确实在dataReceive事件上设置了一个断点,但它没有收到任何事件。当屏幕加载时,它只接收一次,但在此之后永远不会收到事件

delegate void SetTextCallback(string text);

SerialPort serRec = null;

SerialPort ser = null;

private void SetText(string text)
    {
        if (this.textBox1.InvokeRequired)
        {
            SetTextCallback d = new SetTextCallback(SetText);
            this.BeginInvoke(d, new object[] { text });
        }
        else
        {
            this.textBox1.Text = text;
        }
    }

private void button1_Click(object sender, EventArgs e)
    {
        serRec = new SerialPort("COM5", 9600, Parity.None, 8, StopBits.One);
        serRec.Open();

        serRec.DataReceived += (sendexr, se) =>
        {
            var r = serRec.ReadLine();
            SetText(r);
        };
        serRec.ReadTimeout = 1000;

        ser = new SerialPort("COM6", 9600, Parity.None, 8, StopBits.One);
        ser.Open();
        while (true)
        {
            ser.WriteTimeout = 1000;
            ser.WriteLine(Guid.NewGuid().ToString());

            System.Threading.Thread.Sleep(3000);
        }
    }

1 个答案:

答案 0 :(得分:3)

这只是猜测,但我的蜘蛛般的感觉告诉我它最有可能是UI线程问题,

SerialPort.DataReceived事件是在一个单独的线程上引发的。如果您需要异步处理数据接收并更新UI,则需要编组回UI线程。

来自MSDN

  

数据时,在辅助线程上引发DataReceived事件   从SerialPort对象收到。因为这个事件是在一个   辅助线程,而不是主线程,试图修改一些   主线程中的元素,如UI元素,可以引发一个   线程异常。如果有必要修改main中的元素   表单或控件,使用Invoke回发更改请求...

<强>〔实施例

private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) {
    var port = (SerialPort)sender;
    string data = port.ReadExisting();

    UpdateGui(data);
}

private void UpdateGui(string data) {
    if (this.InvokeRequired) {
        this.Invoke(new Action( d => UpdateGui(d) ));
        return;
    }

    this.txtBox1.Text = data;
}

注意:这可能对控制台应用程序没有影响的原因是因为您可以在任何线程上写入控制台。

Control.InvokeRequired Property

  

获取一个值,该值指示调用者是否必须调用invoke方法   在对控件进行方法调用时,因为调用者在a上   与创建控件的线程不同的线程。

Control.Invoke Method (Delegate)

  

在拥有控件的线程上执行指定的委托   底层窗口句柄。

更新

来自MickyD的评论

  

最好使用BeginInvoke而不是Invoke,后者可以导致   死锁

Control.BeginInvoke Method (Delegate)

  

在该线程上异步执行指定的委托   控件的底层句柄是在。上创建的。