对于C#中的串行端口编程,当我处于DataRecived处理程序的中间时,如何跳到另一个DataRecivedHandl

本文关键字:中间 程序 何跳 DataRecivedHandl 另一个 处理 串行端口 编程 对于 DataRecived | 更新日期: 2023-09-27 18:25:27

我有一个串行端口和一堆DataRecived处理程序,如果某个条件在另一个处理程序中为真,我希望在某个时刻激活其中一个。例如

 // write some message to StartCommHandler
 private void StartCommHandler(object sender, SerialDataReceivedEventArgs e)
    {
        SerialPort sp = (SerialPort)sender;            
        byte[] startComResp = new byte[7];             
        if (sp.BytesToRead < 7)
            return;
        else
            sp.DataReceived -= StartCommHandler;

        sp.Read(startComResp, 0, startComResp.Length);

        if ( //true response)
        {
            // enable StartMeasureHandler and write to it:
            sp.DataReceived += StartMeasureHandler;
            // write some message to StartCommHandler
        }
        else
        {
            // enable StartCommHandler and write to it again:
            sp.DataReceived += StartCommHandler;
            // write the message to StartCommHandler
        }
      // some other code that should not be read if else is selected
    }
  private void StartMeasureHandler(object sender, SerialDataReceivedEventArgs e)
    {
     //some code
    }

当我启用"StartMeasureHandler"并写入它时,我希望我应该跳转到它,而其余的代码应该被忽略。但它继续读取"StartCommHandler"中的其余代码。

换句话说,我应该如何从一个处理程序跳到另一个处理

p.s.:我知道我可以把代码放在if-else语句中,但我仍然需要知道我的问题的解决方案,以解决更复杂的问题。

感谢

对于C#中的串行端口编程,当我处于DataRecived处理程序的中间时,如何跳到另一个DataRecivedHandl

TL;DR:只有一种处理串行流的好方法——使用状态机。让编译器为您编写状态机,并感到高兴。


甚至比交换事件处理程序更好的是根本不使用DataReceived事件。使用sp.BaseStream.ReadAsync。然后,您可以用阻塞风格编写所有数据处理代码,这很容易,编译器会将其转换为连续传递风格,这表现得很好。

没有线程可乱。并且它绕过了SerialPort类中最容易出错的部分。

我已经写了一篇关于这个主题的博客文章,你可以阅读它来了解为什么要避免DataReceivedBytesToRead的更多细节。

您应该能够调用

if ( /*true response*/)
{
    sp.DataReceived += StartMeasureHandler;
    StartMeasureHandler(object sender, SerialDataReceivedEventArgs e);
    return;
}
// ...

它仍然只是一个函数。