使用BaseStream.BeginRead从COM端口读取并获取子字符串

时间:2017-05-31 12:59:32

标签: c# winforms serial-port

我试图从com端口读取,这是我的代码

   public string HouseState()
    {
        string state = string.Empty;
     if (!Variables.portBusy)
            {
                // Begin communications
                var blockLimit = 13;
                openSerial();
                byte[] buffer = new byte[blockLimit];
                Action kickoffRead = null;

                kickoffRead = delegate
                {
                    serialPort.BaseStream.BeginRead(buffer, 0, buffer.Length, delegate (IAsyncResult ar)
                    {
                        try
                        {
                            int actualLength = serialPort.BaseStream.EndRead(ar);
                            byte[] received = new byte[actualLength];
                            Buffer.BlockCopy(buffer, 0, received, 0, actualLength);
                            state += System.Text.Encoding.UTF8.GetString(received);
                            //MessageBox.Show(state);
                        }
                        catch (IOException exc)
                        {
                            //handleAppSerialError(exc);
                        }
                        if (state.Count() <= 13)
                            kickoffRead();
                    }, null);
                };
                kickoffRead();
            }
        MessageBox.Show(state);
        var index = state.IndexOf("R");
        var command = string.Empty;
        if (index >= 0)
            command = state.Substring(index, 13);


        return command;
    }

我想要得到的是一个以R开头且有13个字符的字符串。因为有时端口发送一半的字符串我这样做: if(state.Count()&lt; = 13)

但是在BaseStream中,状态字符串得到我想要的,当我尝试读取状态字符串时,它显示为空。 MessageBox显示一个空字符串。

为什么会这样?

1 个答案:

答案 0 :(得分:2)

BeginRead的{​​{1}}方法是异步的,所以当您进入SerialPort.BaseStream时,实际的阅读可能还没有完成,MessageBox.Show(state);仍然是空。您需要等到读取所有必要的数据:

state

说过基于// ..................... var readComplete = new ManualResetEvent(false); kickoffRead = delegate { serialPort.BaseStream.BeginRead(buffer, 0, buffer.Length, delegate (IAsyncResult ar) { // ................... if (state.Count() <= 13) kickoffRead(); else readComplete.Set(); }, null); }; kickoffRead(); readComplete.WaitOne(); // ...................... / BeginRead的异步读取被EndRead取代。根据您的原始片段,即使是同步读取也是可以接受的。您可以在此问题的答案中找到两者的示例:C# Async Serial Port Read