我试图从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() <= 13)
但是在BaseStream内部,状态字符串得到我想要的东西,当我试图读取状态字符串时,它看起来是空的。MessageBox显示一个空字符串。
为什么会发生这种事?
发布于 2017-05-31 13:19:17
BeginRead
方法的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
的异步读取被ReadAsync
one所取代。根据您的原始代码段,即使同步读取在您的情况下也是可以接受的。您可以在这个问题的答案中找到这两个问题的示例:C# Async Serial Port Read
https://stackoverflow.com/questions/44285526
复制相似问题