Thread-Interrupt, der nicht beendet wird, blockiert Anruf beim Eingangsstrom, der gelesen wird

8

Ich verwende RXTX, um Daten von einem seriellen Port zu lesen. Das Lesen erfolgt in einem Thread, der wie folgt erzeugt wird:

%Vor%

Die SerialReader-Klasse implementiert Runnable und führt eine unbegrenzte Anzahl von Loops durch, liest vom Port und erstellt die Daten in nützliche Pakete, bevor sie an andere Anwendungen gesendet wird. Allerdings habe ich es auf die folgende Einfachheit reduziert:

%Vor%

Wenn ein Benutzer auf eine Stoppschaltfläche klickt, wird die folgende Funktionalität ausgelöst, die theoretisch den Eingabestream schließen und den blockierenden byteChan.read (Puffer) -Aufruf unterbrechen sollte. Der Code ist wie folgt:

%Vor%

Wenn ich diesen Code ausführe, erhalte ich jedoch nie eine ClosedByInterruptException, die ausgelöst werden soll, sobald der Eingabestream schließt. Außerdem blockiert die Ausführung beim Aufruf von serial.close () - weil der zugrundeliegende Eingabestream beim Lesen weiterhin blockiert. Ich habe versucht, den Unterbrechungsaufruf mit byteChan.close () zu ersetzen, der dann eine AsynchronousCloseException verursachen sollte, jedoch erziele ich die gleichen Resultate.

Jede Hilfe zu dem, was mir fehlt, wäre sehr willkommen.

    
JDS 01.10.2010, 22:11
quelle

3 Antworten

3

Der RXTX SerialInputStream (was vom Aufruf serial.getInputStream () zurückgegeben wird) unterstützt ein Timeout-Schema, das letztendlich alle meine Probleme löste. Wenn vor dem Erstellen des neuen SerialReader-Objekts Folgendes hinzugefügt wird, werden die Lesevorgänge nicht mehr unbegrenzt blockiert:

%Vor%

Innerhalb des SerialReader-Objekts musste ich einige Dinge ändern, um direkt aus dem InputStream lesen zu können, anstatt den ReadableByteChannel zu erstellen, aber jetzt kann ich den Reader ohne Probleme stoppen und neu starten.

    
JDS 13.10.2010, 17:31
quelle
5

Sie können einen Stream, der interruptable I / O nicht unterstützt, nicht einfach in einen InterruptibleChannel umwandeln, indem Sie ihn umschließen (und ReadableByteChannel erweitert InterruptibleChannel nicht).

Sie müssen sich den Vertrag des zugrunde liegenden InputStream anschauen. Was sagt SerialPort.getInputStream() über die Unterbrechbarkeit seines Ergebnisses? Wenn es nichts sagt, sollten Sie davon ausgehen, dass es Interrupts ignoriert.

Für alle E / A, die die Unterbrechbarkeit nicht ausdrücklich unterstützen, besteht die einzige Option darin, den Stream im Allgemeinen aus einem anderen Thread zu schließen. Dies kann sofort einen IOException (obwohl es möglicherweise kein AsynchronousCloseException ist) in dem Thread auslösen, der bei einem Aufruf des Streams blockiert ist.

Aber auch dies ist extrem abhängig von der Implementierung von InputStream - und das zugrundeliegende OS kann ebenfalls ein Faktor sein.

Beachten Sie den Quellcode-Kommentar für die Klasse ReadableByteChannelImpl , die von newChannel() zurückgegeben wird:

%Vor%     
erickson 01.10.2010 22:22
quelle
1

Ich verwende den folgenden Code, um rxtx herunterzufahren. Ich führe Tests aus, die sie starten und herunterfahren und das scheint gut zu funktionieren. Mein Leser sieht so aus:

%Vor%

Danke

%Vor%     
Ray Tayek 30.11.2010 08:50
quelle