c# 串口自动适配波特率 通讯失败

想做一个串口的握手功能,遇到下面的问题:
当baudRateList 只有一个9600时,通讯可以成功;
但当baudRateList 中有多个波特率时,就通讯不上了。
求指教,在线等。

    using System.IO.Ports;

    public class MySerialPort : SerialPort 
    {
       // public readonly int[] baudRateList = { 9600 };
       private readonly int[] baudRateList = { 115200, 57600, 38400, 19200, 9600 };
       public string receivedString;
       public ManualResetEvent receivedFlag = new ManualResetEvent(false);

        public bool HandShake()
        {
            bool ret = false;
            int handShakeLimits = 4;
            int retryCount;
            foreach (int baudRate in baudRateList)
            {
                this.BaudRate = baudRate;
                this.Close();
                this.Open();
                this.DiscardInBuffer();
                this.DiscardOutBuffer();

                this.Write(GetInstructions.serialNum + "\n");
                // 等待100毫秒,检查 receivedFlag是否设置为true。如果没有,继续循环
                retryCount = 0;
                while (!receivedFlag.WaitOne(100))
                {
                    if (retryCount++ >= handShakeLimits)
                    {
                        receivedFlag.Reset();
                        break;
                    }
                }

                if (retryCount < handShakeLimits)
                {
                    ret = true;
                    break;
                }
            }
            return ret; 
        }

        public void GppSerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            receivedFlag.Set();
            if (sender is SerialPort serialPort)
            {
                // 将缓冲区回车符前所有内容读取出来
                ReceivedString = serialPort.ReadLine();
                serialPort.DiscardInBuffer();
                serialPort.DiscardOutBuffer();
            }
        }
    }

我随手写一个看看,没设备。所以只是演示如何做这种传统的异步回调的同步模拟方法

public class MySerialPort : SerialPort
        {

            public MySerialPort(string portName) : base(portName)
            {

            }
            private readonly int[] baudRateList = { 115200, 57600, 38400, 19200, 9600 };
            public bool CheckHandShake()
            {
                bool ret = false;
                int handShakeLimits = 4;
                int retryCount;
                foreach (int baudRate in baudRateList)
                {
                    if (this.IsOpen)
                    {
                        this.Close();
                    }

                    this.BaudRate = baudRate;
                    this.Open();
                    this.DiscardInBuffer();
                    this.DiscardOutBuffer();
                    this.Write("xxx" + "\n");
                    if (CheckProtcol())
                    {
                        break;
                    }

                }
                return ret;
            }

            private bool CheckProtcol()
            {
                //你这里都用传统代码,所以我们也不用啥task异步一类的玩意,免得废半天劲,你来句我net2的
                
                ManualResetEvent receivedFlag = new ManualResetEvent(false);
                bool Received = false;
                SerialDataReceivedEventHandler mye = null;

                //这里直接定义局部委托,使用函数式手段将逻辑封在一个方法,避免传统的vb,net1.1时代那种事件割裂逻辑,造成你原来那种看着的费劲的代码
                mye = ((send, e) =>
                 {
                     //这里其实还有一些协议内容检查,我就不想写了,但是你那里不能已是否收到数据为基准,比如modbus你发给他不认识的,他会回发一个error封包,所以还是以双方约定的协议内容为基准,而不是以收到为基准
                     this.DataReceived -= mye;
                     Received = true;
                     receivedFlag.Set();
                 });
                this.DataReceived += mye;
                receivedFlag.WaitOne(400); //这里直接使用400ms超时,不需要用哪个看着郁闷的计数器,逻辑上是有符合需要的数据set就通过了,没有符合的数据最多等待400ms
                if (!Received)
                {
                    this.DataReceived -= mye; //如果没有复合的数据,把临时给的委托注销掉,避免后续进入
                }
                return Received;


            }

        }



代码写的不太好看。所以我就不仔细看了。

所以我就说2个点
1.检查那个锁。单个能进,多个不能进,那么我怀疑这个锁(当然这里为啥弄个锁也是很奇怪啊)
2。检查isopen的情况,串口是独占,他不能重复打开,所以尝试修改波特率前需要保证串口是关闭的