2016-07-08 21 views
0

Ich erstelle eine UWP-Anwendung, die Daten von einem USB-Eingabegerät über den virtuellen seriellen Anschluss lesen muss, den sie verfügbar macht.So leeren Sie den Eingabepuffer eines SerialDevice

Ich habe this tutorial verwendet, um einen funktionierenden Prototyp unter Verwendung der SerialCommunication.SerialDevice Klasse zu erreichen. Allerdings muss ich den Eingabestrom beim ersten Öffnen der seriellen Schnittstelle leeren, um unerwünschte Daten zu löschen, die sich möglicherweise im Puffer des Eingabegeräts befinden, bevor die Anwendung eine Verbindung herstellt.

Die offensichtliche Lösung scheint zu sein, den Port weiter zu lesen, bis nichts mehr zu lesen ist; so etwas wie diese:

uint bytes; 

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

Dies ist jedoch nicht funktioniert, weil LoadAsync() wartet auf unbestimmte Zeit, wenn es keine Daten zu lesen.

Gibt es eine Möglichkeit, den Inhalt des Eingabestreams abzufragen, bevor Sie versuchen, es zu lesen, oder alternativ, ihn unbedingt zu löschen?

Vielen Dank für Ihre Anregungen,

Tim

UPDATE: Als Reaktion auf die Kommentare von @Hans Passant, modifizierte ich den Code als Inhalt in dem Eingangspuffer zu erkennen folgt, bevor es zu lesen:

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 

Also, trotz Warte 1000 ms (das Gerät ausreichend Zeit, um zu senden, was in seinem Puffer ist), BytesReceived nicht alle Daten zu erfassen, aber LoadAsync liest 75 Bytes unmittelbar danach.

+0

Verwenden Sie die SerialDevice.BytesReceived-Eigenschaft, um zu ermitteln, wie viele Bytes Sie lesen können, ohne zu blockieren. –

+0

@Hans Danke - toller Vorschlag - aber das scheint nicht zu funktionieren. Wenn ich SerialDevice.BytesReceived lese, wird immer Null zurückgegeben, obwohl ein sofortiger Folgeaufruf an _dataReader.LoadAsync einen positiven Wert zurückgibt. –

+0

Es ist mir nicht klar, warum Sie versuchen, überhaupt zu löschen, wenn BytesReceived 0 ist. Die logischste Erklärung ist, dass das Gerät sofort etwas sendet, wenn es die Handshake-Signale anschaltet. Aber das braucht Zeit, mindestens eine Millisekunde bei 9600 Baud. Wenn Sie diese auch loswerden möchten, müssen Sie Task.Delay() für 100 ms geben oder nehmen. –

Antwort

0

DataReader.LoadAsync() wird erst zurückgegeben, wenn ein oder mehrere Bytes empfangen wurden. Wenn Ihr Eingabepuffer leer ist, wird Ihr Code blockiert.

Mit dem CancellationToken können Sie die Leseaufgabe abbrechen, um den seriellen Eingangspuffer zu "leeren".

Unten ist der Code, der den Trick macht.

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

Danke, das ist eine kluge Lösung für das Problem. –