简体   繁体   English

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

[英]Reading from COM port with BaseStream.BeginRead and getting a substring

Im trying to read from a com port, this is my code 我试图从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;
    }

What im trying to get is a string that starts with R and has 13 characters. 我试图得到的是一个以R开头并包含13个字符的字符串。 Because sometimes the port sends half the string i do this: if (state.Count() <= 13) 因为有时端口会发送一半的字符串,所以我这样做: if(state.Count()<= 13)

But while inside BaseStream the state string gets what i want, when i try to read the string of state, it appears empty. 但是,在BaseStream中,状态字符串会得到我想要的,当我尝试读取状态字符串时,它看起来为空。 The MessageBox shows an empty string. MessageBox显示一个空字符串。

why this is happening? 为什么会这样呢?

The BeginRead method of SerialPort.BaseStream is asynchronous so by the moment you're getting to MessageBox.Show(state); SerialPort.BaseStreamBeginRead方法是异步的,因此在您进入MessageBox.Show(state);的那一刻MessageBox.Show(state); the actual read may have not completed yet and state is still empty. 实际读取可能尚未完成,并且state仍然为空。 You need to wait until all necessary data is read: 您需要等待,直到读取了所有必要的数据:

// .....................
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();
// ......................

Having said that BeginRead / EndRead based async reading is superseded by ReadAsync one. 话虽如此,基于BeginRead / EndRead的异步读取已被ReadAsync取代。 And based on your original snippet even synchronous read is acceptable in your case. 根据您的原始代码段,即使是同步读取在您的情况下也是可以接受的。 You may find examples for both in the answers to this question: C# Async Serial Port Read 您可以在此问题的答案中找到两个示例: C#异步串行端口读取

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM