SerialPort DataReceived->Invoke->Port.Close() Form hängt

  • VB.NET

Es gibt 2 Antworten in diesem Thema. Der letzte Beitrag () ist von Niko Ortner.

    SerialPort DataReceived->Invoke->Port.Close() Form hängt

    Hallo

    Ich habe ein seltsames Problem. Ich erkläre erst mal mein Vorhaben:

    Das Programm kommuniziert über eine serielle Schnittstelle mit einem Microcontroller.
    Dieser arbeitet abhängig von den empfangenen Daten Code ab und sendet 1 (OK) oder 2 (Fehler) zurück.
    Vor dem Senden an den µC wird abgespeichert was gesendet wurde, damit beim Auftreten des DataReceived Events noch bekannt ist was der µC gerade machen sollte.
    Die Daten werden vom Programm gesendet und der µC empfängt sie ordnungsgemäß.
    Das Zurücksenden funktioniert auch problemlos.
    Allerdings kommt es zu Problemen wenn der µC zurücksendet und die Verbindung geschlossen werden soll.
    Beim Empfang von Daten wird in der Sub die das .DataReceived Event handelt
    Me.Invoke(New EventHandler(AddressOf STAThread_Connection_DataReceived))
    aufgerufen. Das war auch so bei Google zu finden (Threadsicherheit).
    Der Präfix STAThread_ stellt hier nur dar, dass diese Sub nicht direkt aufgerufen wird, sondern über Me.Invoke.


    Der Ablauf ist so:

    1. Aufruf der Sub Connection_Close
    2. Zwischenspeichern von 1 (Bedeutet Debugging beenden)
    3. Senden von 1

    4. DataReceived wird ausgelöst
    5. Me.Invoke
    6. Anhand des zwischengespeicherten Wertes (1) wird eine Sub aufgerufen
    7. Wenn der empfangene Wert 1 (OK) ist (wird mit .ReadByte ausgelesen) wird eine andere Sub aufgerufen
    8. In dieser Sub wird die .Close Methode des SerialPorts aufgerufen (Und ein paar Button Eigenschaften geändert).



    Bis zur letzten Sub funktioniert es perfekt. Haltepunkt setzen -> wird gestoppt.
    Aber wenn dann (per Einzelschrittdebugging oder normal) .Close aufgerufen wird hängt das Programm (Schema Endlosschleife).
    Wenn man im Visual Studio den "Alle unterbrechen" Button klickt (Sieht aus wie ein Pausieren Zeichen) wird .Close grün markiert. Seit neuestem wird manchmal auch Me.Invoke(...) markiert.
    Wenn man für SerialConnection eine Überwachung hinzufügt wird
    "Der Ausdruck kann nicht ausgewertet werden, da der Code der aktuellen Methode optimiert wurde."
    angezeigt.
    Falls es hilft hier ein Screenshot:

    Ich hab das Programm mehrere Minuten laufen lassen, aber es hängt nur.
    Wenn man .Close irgendwo anders im Code aufruft funktioniert es tadellos. Auch wenn man die selbe letzte Sub aufruft.

    Gibt's da was was ich vor dem Schließen machen muss?
    Alternativ kann ich ja in einem BGW permanent BytesToRead überprüfen und wenn Daten gelesen werden sollen per .ReportProgress den GUI Thread benachrichtigen.
    Wie gesagt: Die Daten werden richtig empfangen und gesendet.


    PS: Warum gibt .ReadByte einen Integer zurück?
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    Ist das ein thread-übergreifendes Close?
    Wenn ja: Vielleicht kannst Du das Close im Original-Thread aufrufen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Es sollte eigentlich nicht Thread übergreifend sein, da ich mit Me.Invoke(New EventHandler(AddressOf...)) eine Methode des GUI Threads aufrufe. Aber es kann sein, dass die SerialPort Klasse das intern anders behandelt.

    Mal sehen ob das Aufrufen von .Close im Originalthread was bringt...

    Ok. Da funktioniert es. Komische Sache. Auf die Controls auf der Form kann ich per Me.Invoke problemlos zugreifen.
    Danke ganz herzlich an Dich.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils