Schrittweises Debugging endet nach Invoke

  • VB.NET
  • .NET (FX) 4.5–4.8

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

    Schrittweises Debugging endet nach Invoke

    Hallo,

    ich habe folgenden Code:

    VB.NET-Quellcode

    1. Private WithEvents nfcScanForm As dlgPersonalnr_NFC
    2. Private Sub Close_NfcForm() Handles nfcScanForm.Close_NfcScanForm
    3. If Not nfcScanForm Is Nothing Then
    4. If nfcScanForm.InvokeRequired Then
    5. nfcScanForm.Invoke(Sub() CloseThisForm(nfcScanForm))
    6. Else
    7. nfcScanForm.Close()
    8. nfcScanForm.Dispose()
    9. End If
    10. nfcScanForm = Nothing
    11. End If
    12. 'Jetzt müssen wir schauen ob die Form groß ist oder normal
    13. 'Und entsprechend die richtigen Statisiken wieder laden
    14. If BigView Then
    15. 'Große Ansicht
    16. OpenChildForm(New dlgStatistics_Big)
    17. Else
    18. 'kleine Ansicht
    19. OpenChildForm(New dlgStatistics_Small)
    20. End If
    21. End Sub
    22. Private Sub CloseThisForm(CloseForm As Form)
    23. CloseForm.Close()
    24. CloseForm.Dispose()
    25. End Sub


    Ich habe hier 2 Haltepunkte gesetzt, 1x in Zeile 2 und 1x in Zeile 14 (If BigView then).
    Ich kann in Einzelschritten jede Zeile bis ich auf "End Sub" der Sub "CloseThisForm" komme.
    Ab da endet das Einzelschritt-Debugging und das Programm läuft im "Live" Modus weiter.
    Warum ist das so, wieso komme ich nicht auf Zeile 9 nachdem die Sub "CloseThisForm" abgearbeitet wurde?
    Habe ich irgend einen Fehler drin und sehe es nicht?

    Danke

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

    Ok, vorab: nfcScanForm ist offensichtlich kein normales Form, sondern ein Derivat, denn ein normales Form hat kein Close_NfcScanForm-Event. Wo ist dieser EventHandler stationiert? Wohl nicht in der nfcScanForm-Klasse, oder? Wann* wird das Close_NfcScanForm-Event von der nfcScanForm-Instanz abgefeuert?

    * Also, in welcher Methode?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Was mir jetzt noch fehlt, um das Problem überhaupt mal nachbauen zu können: Wie wird nfcScanForm instanziiert und nebenläufig aufgerufen? Denn nebenläufig ist das Ganze, sonst wäre das mit dem InvokeRequired nicht nötig. Aber ich brauche mit meinem Versuchen gar kein Invoke:

    Also machst Du es wohl anders.

    Auch wenn nfcScanForm bei der Deklaration und nicht im Nebenläufigkeitsbereich instanziiert wird, kommt es nicht zum InvokeRequired-Pfad.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Montoyafan schrieb:

    Ab da endet das Einzelschritt-Debugging und das Programm läuft im "Live" Modus weiter.
    Klar, weil Du in den Main-Thread invokt hast, um genau eine einzelne Prozedur abzuarbeiten.
    Da es in diesem Sinne kein Zurück-Invoken gibt, macht der Debugger in der Message-Loop weiter.
    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!
    Ja, etwas anders ^^

    VB.NET-Quellcode

    1. Private Sub Get_NFCTag() Handles btnGetNFC.Click
    2. If nfcScanForm Is Nothing Then nfcScanForm = New dlgPersonalnr_NFC
    3. OpenChildForm(nfcScanForm)
    4. End Sub
    5. Friend Sub OpenChildForm(OpenForm As Form)
    6. 'Hat activeChildForm bereits eine Form, schliessen
    7. If Not IsNothing(activeChildForm) Then
    8. activeChildForm.Close()
    9. activeChildForm = nothing
    10. End If
    11. activeChildForm = OpenForm
    12. OpenForm = Nothing
    13. activeChildForm.TopLevel = False
    14. activeChildForm.FormBorderStyle = FormBorderStyle.None
    15. activeChildForm.Dock = DockStyle.Fill
    16. If panel_Statistik.InvokeRequired Then
    17. panel_Statistik.Invoke(Sub() InvokePanel())
    18. Else
    19. panel_Statistik.Controls.Clear()
    20. panel_Statistik.Controls.Add(activeChildForm)
    21. panel_Statistik.Tag = activeChildForm
    22. activeChildForm.BringToFront()
    23. activeChildForm.Show()
    24. End If
    25. End Sub

    RodFromGermany schrieb:

    Da es in diesem Sinne kein Zurück-Invoken gibt, macht der Debugger in der Message-Loop weiter.
    Dann dürfte das hier m.E. gar nicht passieren:


    @Montoyafan: Aber da ist doch wieder kein nebenläufiger Subform-Aufruf. Oder was steckt hinter InvokePanel, was ja aufgerufen wird, wenn panel_Statistik irgendwas mit Nebenläufigkeit zu tun hat, wenn da wieder mit InvokeRequired gearbeitet wird? An welcher Codestelle wird das Ganze nebenläufig?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    InvokePanel enthält das gleiche wie im Else-Strang steht.

    Wenn ich das Beispiel in einem neuen Projekt nachbaue komme ich auch nicht auf den InvokeRequired-Pfad. ?(

    Zur Erklärung: Ich habe in der MainForm ein Panel panel_Statistik, in dem ein Form dlgStatistics_Small standartmäßig geladen wird.
    Klickt der User auf einen Button in der MainForm, wird dlgStatistics_Small in diesem Panel "entladen" und die NFC-Form darin angezeigt.
    Sobald der Scan erfolgreich war, soll das NFC-Form wieder entladen werden und dlgStatistics_Small (bzw. dlgStatistics_Big) wieder angezeigt werden.
    Daher die Frage, wo die Nebenläufigkeit quasi anfängt. Es muss ja sowas sein mit Threading.Thread oder Threading.Tasks.Task. Oder z.B. ein Aufruf einer Frameworkfunktion, die selber was nebenläufiges startet.

    Zu Deiner Erklärung: Ok, kann ich nachvollziehen. Aber es erklärt eben die Nebenläufigkeit noch nicht, die ja das Ganze InvokeRequired-Gedöns anscheinend notwendig macht.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Die NFC Form startet einen Thread.

    VB.NET-Quellcode

    1. ​Public Class dlgPersonalnr_NFC
    2. Public Event Close_NfcScanForm()
    3. Public Event Set_PersNr(ByVal stamp As String)
    4. Private myThread As New ThreadStart(AddressOf wait_forScan)
    5. Private WaitForScan_Thread As Thread
    6. Private Sub rfid_scan_Shown(sender As Object, e As EventArgs) Handles Me.Shown
    7. 'auf einen neuen Scan warten in eigenem Thread
    8. If ReaderConnected Then
    9. WaitForScan_Thread = New Thread(myThread) With {
    10. .IsBackground = True
    11. }
    12. WaitForScan_Thread.Start()
    13. End If
    14. End Sub
    15. Private Sub wait_forScan()
    16. Dim cardID As String = ""
    17. If lblStatus.InvokeRequired Then
    18. lblStatus.Invoke(Sub() lblStatus.Text = "Warte auf Transponder-Scan...")
    19. Else
    20. lblStatus.Text = "Warte auf Transponder-Scan..."
    21. End If
    22. While Me.connectCard = False
    23. 'Thread für 1 Millisekunde schlafen lassen
    24. Thread.Sleep(1)
    25. 'Abbrechen und SUB verlassen wenn ein Read-Abbruch angefordert wurde
    26. If StopReading Then
    27. Invoke(Sub() lblStatus.Text = "Lese-Pause")
    28. Return
    29. End If
    30. End While
    31. If lblStatus.InvokeRequired Then
    32. lblStatus.Invoke(Sub() lblStatus.Text = "Transponder erkannt")
    33. Else
    34. lblStatus.Text = "Transponder erkannt"
    35. End If
    36. cardID = getcardUID()
    37. If cardID <> "Error" AndAlso cardID <> "63000000" Then
    38. Dim stamp As String = dbModul.Get_StampFromRFID(cardID)
    39. If stamp <> "" Then
    40. SendStamp(stamp)
    41. Else
    42. Thread.Sleep(3000)
    43. WaitForScan_Thread = New Thread(myThread)
    44. WaitForScan_Thread.Start()
    45. End If
    46. Else
    47. If lblStatus.InvokeRequired Then
    48. lblStatus.Invoke(Sub() lblStatus.Text = "Fehler beim Lesen, bitte nochmal versuchen")
    49. Else
    50. lblStatus.Text = "Fehler beim Lesen, bitte nochmal versuchen"
    51. End If
    52. Thread.Sleep(3000)
    53. WaitForScan_Thread = New Thread(myThread)
    54. WaitForScan_Thread.Start()
    55. End If
    56. End Sub
    57. Private Sub SendStamp(stamp As String)
    58. RaiseEvent Set_PersNr(stamp)
    59. CloseForm
    60. End Sub
    61. Private Sub CloseForm()
    62. RaiseEvent Close_NfcScanForm()
    63. End Sub
    64. End Class
    @VaporiZed Missverständnis.
    Haltepunkt in CloseThisForm().
    Wenn CloseThisForm() beendet ist, ist das Ander-Thread-Intermezzo beendet.
    Das ist eine temporäre Task.
    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!