Reputation: 8927
I'm creating a UWP application that needs to read data from a USB input device via the virtual serial port that it exposes.
I have used this tutorial to achieve a working prototype using the SerialCommunication.SerialDevice
class. However, I need to flush the input stream when the serial port is first opened, to discard any unwanted data that may be in the buffer of the input device before the application connects to it.
The obvious solution seems to be to keep reading the port until there is nothing left to read; something like this:
uint bytes;
do
{
bytes = await _dataReader.LoadAsync(ReadBufferLength);
_dataReader.ReadString(bytes);
} while (bytes > 0);
However, this doesn't work because LoadAsync()
waits indefinitely if there is no data to read.
Is there a way to query the contents of the input stream before attempting to read it, or alternatively to unconditionally flush it?
Thanks for your suggestions,
Tim
UPDATE: In response to comments from @Hans Passant, I modified the code as follows to detect content in the input buffer before attempting to read it:
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
So, despite waiting 1000ms (to allow the device adequate time to send what is in its buffer), BytesReceived
fails to detect any data, but LoadAsync
reads 75 bytes immediately afterwards.
Upvotes: 0
Views: 2574
Reputation: 2030
DataReader.LoadAsync() won't return until one or more bytes are received. In case your input buffer is empty, it'll block your code.
You can use the CancellationToken to cancel the read task in order to "flush" the serial input buffer.
Below is the code that does the trick.
using (var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(1000)))
{
await dataReaderObject.LoadAsync(1024).AsTask(cts.Token);
}
Upvotes: 1