Мне нужна помощь в чтении данных с последовательного порта, подключенного к устройству с интерфейсом RS-232. Я решил использовать стиль async
/ await
, поскольку данные будут постоянно обновляться в графическом интерфейсе, который должен оставаться чувствительным к пользователю.
Приведенный ниже код является сущностью моей текущей реализации.
private async void MyReadFromSerialPortMethod()
{
// (this.serialPort is a System.IO.Ports.SerialPort instance.)
this.serialPort.DiscardInBuffer();
this.serialPort.DiscardOutBuffer();
this.serialPort.Write(/* bytes for "please send me some data now", 0, length */);
byte[] header = new byte[3];
await this.serialPort.BaseStream.ReadAsync(header, 0, header.Length);
// do something with the header info first,
// like check what kind of data is incoming
byte[] data = new byte[5];
await this.serialPort.BaseStream.ReadAsync(data, 0, data.Length);
// do something with the data,
// like show it to the user eventually
}
Моя проблема в том, что в приведенном выше коде вызовы ReadAsync
обычно читают только один байт с входа и затем возвращаются из await
(не всегда , но обычно). Если бы я использовал синхронные методы, я мог бы сделать так, чтобы ReceivedBytesThreshold
содержал необходимое количество байтов, но не хотел бы удерживать поток пользовательского интерфейса, пока я делаю это. Насколько я знаю, для ReadAsync
нет такого порога для задержки возвращения. Это было бы очень полезно.
Я реализовал следующее в качестве обходного пути, но мне это не кажется хорошим решением. Зацикливание на асинхронном методе похоже на то, что я просто пишу цикл ожидания занятости, чтобы дождаться заполнения входного буфера, и я мог бы также использовать синхронную версию. Хотя я знаю, что await
, вероятно, в некоторой степени возвращает управление вызывающей стороне между каждым поступающим байтом, речь идет не о профилировании кода для скорости и эффективности, а скорее о том, каков правильный шаблон кодирования и использую ли я преимущество асинхронного программирования или препятствия.
byte[] header = new byte[3];
int bytesRead = 0;
while (bytesRead < header.Length)
{
bytesRead += await this.serialPort.BaseStream.ReadAsync(header, bytesRead, header.Length-bytesRead);
}
// similarly for byte[] data...