我试图从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显示一个空字符串。
为什么会这样?
答案 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