Bei komunikation über Serielle Schnittstelle blockiert das Form1

  • VB.NET

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Bei komunikation über Serielle Schnittstelle blockiert das Form1

    Hallo VB_Freunde,
    ich habe eine Software erstellt zum ansteuern einer CNC Maschine über einen GRBL Controller (Arduino). Die Kommunikation findet über die Serielle Schnittstelle statt.
    Jeder Befehl der zum GRBL gesendet wird, wird mit einem ok oder error bestätigt. Über ein DataReceived Event abgefangen und ausgewertet, error wird noch nicht ausgewertet. Über eine while-Schleife warte ich auf ein ok und Sende dann den nächsten Befehl. Das funktioniert sehr gut, aber wenn die Befehle gesendet werden, blockiert die Oberfläche vom Programm und ich habe keine Möglichkeit einzugreifen. Es kommen schnell mal 3000 Befehle zusammen, das kann schon lange dauern. Gibt es eine Möglichkeit das anders zu machen? Oder irgendwie eine Pause Funktion einzubauen, da mein Programm nicht mehr reagiert, habe ich keine Idee.

    Hier der DataReceived Event

    VB.NET-Quellcode

    1. ​Private Sub SerialPort1_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
    2. ReceivedText(SerialPort1.ReadLine())
    3. End Sub
    4. Private Sub ReceivedText(ByVal [text] As String)
    5. If text.Contains("ok") Then
    6. befehl_ok = True
    7. End If
    8. End Sub
    9. und die warte schleife
    10. Private Sub warten()
    11. While befehl_ok = False
    12. End While
    13. befehl_ok = False
    14. End Sub



    Ich hoffe es kann mir jemand helfen, Danke.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Buzii“ ()

    VB.NET-Quellcode

    1. While befehl_ok = False
    2. End While

    Endlosschleife. Dürfte das GUI blockieren. Egal, ob Befehle kommen oder nicht. Nutze Nebenläufigkeit für den Befehlsempfänger, Stichwort Async/Await.

    btw: Bitte CodeTags nutzen und nicht Code in den Fließtext einarbeiten.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    @Buzii Deine endlosschleife sowie Async/Await ist nicht erdforderlich, da das SerialPort eh in einem anderen Thread arbeitet.
    Wenn eine Meldung kommt, bearbeite sie.
    Das einzige, was Du beachten musst, ist, dass Du zur Darstellung empfangener Strings in den MainTheread invoken musst, sonst kommt eine entsprechende Exception.
    msdn.microsoft.com/en-us/library/aa334867(v=vs.71).aspx
    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).
    VB-Fragen über PN / Konversation werden ignoriert!
    @Buzii Der hat damit nix zu tun.
    Wenn Du eine Pizza bestellst, rennst Du doch nicht alle 15 Sekunden zur Tür, sondern wartest, bis der Bote klingelt.
    Du musst lernen, asynchron zu denken.
    Die Form macht nix, sie ist nicht blockiert, und wenn was vom SerialPort kommt, wird das verarbeitet.
    Feddich.
    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).
    VB-Fragen über PN / Konversation werden ignoriert!
    Hallo Freunde, ich habe es mit dem Thread hinbekommen, Danke dafür.
    Was ich nicht begreife, ich kann nicht direkt aus Thread 2 auf z.b. Textbox zugreifen, da sie im MainThread liegen, dazu brauche ich Invoke. Auf Globale Variablen kann ich aber zugreifen.
    Was ist wenn ich aus Thread 2 ein SUB aufrufe, läuft es dann auch auf Thread 2?
    Was währe wenn ich ein SUB in beiden Threads gleichzeitig aufrufen würde, würden die sich gegenseitig beeinflussen?
    Muss ich das Thread 2 nach dem beenden extra schließen?
    Kann ich das Thread 2 vom MainThread aus schließen oder muss es vom Thread 2 aus geschlossen werden?
    Hier noch ein sehr einfaches Beispiel das mir sehr geholfen hat.

    VB.NET-Quellcode

    1. Delegate Sub WriteTextDelegate(ByVal Target As Label, ByVal Text As String)
    2. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    3. Dim Thread As New Threading.Thread(AddressOf Test)
    4. Thread.Start()
    5. End Sub
    6. Private Sub Test()
    7. For i = 0 To 123456
    8. Dim Params(1) As Object
    9. Params(0) = Label1
    10. Params(1) = i.ToString
    11. Me.Invoke(New WriteTextDelegate(AddressOf WriteText), Params)
    12. Next
    13. End Sub
    14. Public Sub WriteText(ByVal Target As Label, ByVal Text As String)
    15. Target.Text = Text
    16. End Sub

    Buzii schrieb:

    Was ist wenn ich aus Thread 2 ein SUB aufrufe, läuft es dann auch auf Thread 2?
    korrekt

    Buzii schrieb:

    Was währe wenn ich ein SUB in beiden Threads gleichzeitig aufrufen würde, würden die sich gegenseitig beeinflussen?
    Kommt auf den Inhalt drauf an. Sie greifen nicht auf dieselben Daten zu, wenn Du das meinst. Wenn in der Sub ne Variable deklariert wird, wird die in beiden Threads unabhängig voneinander deklariert. Die Subs laufen parallel nebeneinander (aber selten synchron!)

    Buzii schrieb:

    Muss ich das Thread 2 nach dem beenden extra schließen?
    Nö. Wenn die Aufgabe erledigt ist, also in Deinem Beispiel die Prozedur Test abgearbeitet ist, ist der Thread durch, also beendet.

    Buzii schrieb:

    Kann ich das Thread 2 vom MainThread aus schließen oder muss es vom Thread 2 aus geschlossen werden?
    Du kannst es vom MainThread aus schließen (dann kommt eben ne ThreadAbortException), aber musst nicht.
    Bevor Du Dich aber mit Threads beschäftigst (was ein eigenes Thema ist und m.E. nix mehr mit dem Angangspost zu tun hat), schau Dir mal lieber Async/Await an. Damit geht Nebenläufigkeit (das hat nicht gleich was mit Threads zu tun) sehr leicht. Ok, leicht ist relativ, ich sag nur Race-Condition, aber das ist ja bei Nebenläufigkeit häufiger mal ein Stolperstein.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    Danke, verstehe es langsam 8o . Ich bin mit dem Ergebnis erst mal zufrieden, jetzt noch mal neu anfangen mit Async/Await habe ich keine Lust, mal abgesehen davon das ich es mir vorher schon mal angesehen habe, aber es nicht verstanden habe und keine einfachen Beispiele gefunden habe.
    Aber vielen dank für die Hilfe!!!
    @Buzii Threads sollten so programmiert werden, dass sie sich selbst beenden, wenn die Arbeit getan ist.
    Arbeitet der Thread in einer Endlosschleife, dann füge ein Flag hinzu, das dem Thread von außen signalisiert, dass er sich beenden soll.
    Einen Thread von außen abzuwürgen ist suboptimal.
    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).
    VB-Fragen über PN / Konversation werden ignoriert!