Laden...

SerialPort Hotplug

Erstellt von ManuelSchmutz vor 10 Jahren Letzter Beitrag vor 10 Jahren 2.625 Views
M
ManuelSchmutz Themenstarter:in
32 Beiträge seit 2013
vor 10 Jahren
SerialPort Hotplug

Hallo!

Ich habe eine Anwendnung in der es notwendig Hotplug eines USB/SerialConverters zu unterstützen.
Soweit alles kein Problem Erkennung von Plug/Unplug funktioniert soweit.
An dem USB/SerialConverter ist ein RFID Leser angeschlossen der in einem Dauer-Read-Modus betrieben wird. Daher ließt meine Applikation zyklisch am SerialPort.
Wird der USB/SerialConverter abgesteckt (unplugged) bekomme ich wie erwartet eine I/O Exception.
Tritt das auf versuche ich ein SerialPort.Close() durchzuführen das ebenfalls eine I/O Exception wirft.
Danach ist SerialPort.IsOpen = false daher weiß die Applikation dass der USB/SerialConverter unplugged ist.

Jetzt meine Frage:
Wird trotz der I/O Exception das SerialPort-Objekt geschlossen und Empfangs- und Übertragungspuffer gelöscht?
Wird trotzdem die Component-Dispose() Methode die die SerialPort.Dispose-Methode (Boolean) welche von SerialPort verwendeten nicht verwalteten Ressourcen und optional die verwalteten Ressourcen freigibt aufgerufen? Sprich werden die Ressourcen freigeben oder muss ich mich da irgendwie noch drum kümmern?

Danke für eure Inputs
und LG

16.842 Beiträge seit 2008
vor 10 Jahren

Dispose von SerialPort flusht den internen Stream und schließt diesen anschließend.
Was Du noch so alles mit nicht verwalteten Ressourcen meinst weiß ich nicht.

Wenn kein Gerät angeschlossen ist würde ich auch kein SerialPort-Objekt halten; sondern dieses erst erstellen, wenn auch ein Gerät gefunden wird.
Dann sind auch alle Ressourcen weg (bei Dispose). Man sollte da schon drauf vertrauen, dass Dispose korrekt implementiert ist und korrekt funktionier, wenn man es richtig verwendet.

M
ManuelSchmutz Themenstarter:in
32 Beiträge seit 2013
vor 10 Jahren

Ich denke du hast mich missverstanden!!
Was Dispose macht weiß ich!!!
Meine Frage ist allerdings ob auch Dispose aufgerufen wird von Close() wenn bei Close() eine IOException geworfen wird weil das Gerät NICHT MEHR vorhanden ist!!

16.842 Beiträge seit 2008
vor 10 Jahren

Geht's freundlicher? 🤔
Ja, normalerweise ruft Close in .NET Implementierungen immer Dispose(true) auf und hat ansonsten keinen Inhalt.
Und dass Du den Inhalt von Dispose / Flush kennst bezweifel ich nach der Reaktion 😉

Mit Google und ".net serialport source code" kriegst Du sogar den Quellcode geliefert.

M
ManuelSchmutz Themenstarter:in
32 Beiträge seit 2013
vor 10 Jahren

Vielen Dank für dein Bemühen!!
hab mir den Source Code angesehen, beantwortet aber immer noch nicht so richtig meine Frage?!
in Close() wird Dispose aufgerufen ...


public void Close()
        {
            Dispose(true);
        }
  
        protected override void Dispose( bool disposing )
        {
            if( disposing ) {
                if (IsOpen) {
                    internalSerialStream.Flush();
                    internalSerialStream.Close();
                    internalSerialStream = null;
                }
            }
            base.Dispose( disposing );
        } 

Können da irgendwelche Leichen entstehen wenn von close() eine IOException geworfen wird oder nicht? (GC??)

Bitte um Antwort

16.842 Beiträge seit 2008
vor 10 Jahren

Da der internalSerialStream bzw. dessen Typ in der MSDN nicht dokumentiert ist kann ichs nicht mit Gewissheit sagen.
Such halt mal nach dem Source im Web des Typs, ob Flush die Exception wirft - wahrscheinlich ist es.
In der Theorie könnte es also sein - wenn Flush die Exception wirft- dann wird das Objekt internalSerialStream nicht genullt.
Da aber das Objekt des Typs SerialPort nach einem Dispose ohnehin unbrauchbar ist, sollte dies eh verworfen werden. Damit _sollten _auch alle internen Ressourcen freigegeben werden.
Sind hier ja offensichtlich keine unmanaged Ressourcen in Verwendung, die der GC nicht wegräumen würde.

M
ManuelSchmutz Themenstarter:in
32 Beiträge seit 2013
vor 10 Jahren

Danke für die Antwort.

Naja Zitat aus MSDN:

SerialPort.Dispose Method (Boolean)
Releases the unmanaged resources used by the SerialPort and optionally releases the managed resources.

Also werden indirekt schon unmanaged Ressources verwendet oder versteh ich das falsch??

849 Beiträge seit 2006
vor 10 Jahren

Hallo,

du kannst davon ausgehen das alles was irgendwie auf die Hardware zugreift irgendwo unmanaged Resourcen benutzt, da die meisten treiber in c oder c++ geschrieben sind.

Du kannst auch davon ausgehen, das nachdem Du das Object disposed hast und die letzte Referenz auf das Objekt zerstört ist, der GC auch den letzten Rest des Speichers oder der Resourcen freigibt. Würde das nicht so sein wäre das ein Leak in der SerialPort Class.

Glaube mir, das wäre inzwischen aufgefallen 😉 Du hast ja auch geschrieben das nach dem plug out IsOpen False ist.. Jetzt schau mal wo er dann beim Dispose garantiert nicht mehr reinläuft. Das zerstören der Referenz auf internalSerialStream erledigt hier wie Abt schon sagte der GC für Dich, indem er die Instanz von SerialPort zerstört. Bei einem der nächsten läufe bemerkt er dann das ja auch keine Referenz auf internalSerialStream mehr besteht und lässt dem Object das selbe Schicksal wiederfahren.

Was ich damit sagen will ist: Sieh zu das Du deine Instanzen immer korrekt abräumst (dispose -> using benutzen wo möglich<- und referenzen nullen).Überlass den Rest dem .Net Framework. Wenn du dann irgendwann ne OutOfMemory bekommst oder dein Com Port rumzickt kannst Du Dir immer noch genug Gedanken machen.

Gruß

M
ManuelSchmutz Themenstarter:in
32 Beiträge seit 2013
vor 10 Jahren

Ok danke für die Antwort

888 Beiträge seit 2007
vor 10 Jahren

Hier noch ein Kommentar am Rande...

Wir hatten mal massenhaft Barcode-Scanner eingesetzt, alle über RS232-USB.
Es hatte sich rausgestellt, dass diese Technolgie in 2 Punkten Probleme macht, erstens beim rein/raus der Verbindung und zweitens im Dauerbetrieb.

Das war so inakzeptabel, dass wir alle Scanner auf native RS232 umgestellt hatten, danach gab's nie wieder Probleme.

Gruß

J.