2016-07-08 4 views
0

Я создаю приложение UWP, которое должно считывать данные с устройства ввода USB через виртуальный последовательный порт, который он предоставляет.Как очистить входной буфер SerialDevice

Я использовал this tutorial для достижения рабочего прототипа с использованием класса SerialCommunication.SerialDevice. Тем не менее, мне нужно очистить входной поток при первом открытии последовательного порта, чтобы отбросить любые нежелательные данные, которые могут находиться в буфере устройства ввода, прежде чем приложение подключится к нему.

Очевидное решение заключается в том, чтобы продолжать читать порт, пока не осталось ничего, что можно было бы прочитать; что-то вроде этого:

uint bytes; 

do 
{ 
    bytes = await _dataReader.LoadAsync(ReadBufferLength); 
    _dataReader.ReadString(bytes); 
} while (bytes > 0); 

Однако, это не работает, потому что LoadAsync() ожидает неопределенно долго, если нет данных для чтения.

Есть ли способ запросить содержимое входного потока, прежде чем пытаться его прочитать, или, альтернативно, безоговорочно очистить его?

Спасибо за ваши предложения,

Tim

UPDATE: В ответ на замечания @Hans Passant, я изменил код следующим образом для определения содержания в буфере ввода, прежде чем пытаться прочитать:

await Task.Delay(1000); 
Debug.WriteLine("BytesReceived: {0}", _serialDevice.BytesReceived); // 0 bytes 
var bytesRead = await _dataReader.LoadAsync(ReadBufferLength); 
Debug.WriteLine("BytesRead: {0}", bytesRead); // 75 bytes 

Таким образом, несмотря на ожидания 1000 мс (чтобы позволить устройству достаточно времени, чтобы отправить то, что находится в буфере), BytesReceived не удается обнаружить какие-либо данные, но LoadAsync читает 75 байт сразу после этого.

+0

Используйте свойство SerialDevice.BytesReceived, чтобы узнать, сколько байтов вы можете прочитать без блокировки. –

+0

@ Спасибо спасибо - большое предложение - но это, похоже, не работает. Если я прочитал SerialDevice.BytesReceived, он всегда возвращает ноль, даже если немедленный последующий вызов _dataReader.LoadAsync возвращает положительное значение. –

+0

Это не кристалл для меня, почему вы пытаетесь очистить вообще, когда BytesReceived равен 0. Наиболее логичным объяснением является то, что устройство немедленно отправляет что-то, когда видит, что сигналы рукопожатия включаются. Но для этого требуется время, по крайней мере, миллисекунда при 9600 бодах. Если вы хотите избавиться от них, то вам нужно Task.Delay() за 100 мс, дайте или возьмите. –

ответ

0

DataReader.LoadAsync() не возвращается до получения одного или нескольких байтов. Если ваш входной буфер пуст, он заблокирует ваш код.

Вы можете использовать CancellationToken для отмены задачи чтения, чтобы «сбросить» буфер последовательного ввода.

Ниже приведен код, который делает трюк.

using (var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(1000))) 
{ 
    await dataReaderObject.LoadAsync(1024).AsTask(cts.Token); 
} 
+0

Спасибо, это умное решение проблемы. –

 Смежные вопросы

  • Нет связанных вопросов^_^