Event unterbricht Sub

  • VB.NET

Es gibt 19 Antworten in diesem Thema. Der letzte Beitrag () ist von Eistee.

    Event unterbricht Sub

    Hi,

    Kann mir jemand mal erklären warum mein/ein Event den Aktuellen ablauf/durchlauf eines Subs komplett unterbricht?
    Also so ganz, ohne das er wieder zum Sub zurück springt ?(

    Hab das So noch nie beobachten können muss ich sagen.
    Eventuell ist es ja ganz logisch, hier mal der Code:

    VB.NET-Quellcode

    1. 'cb_Drives_SelectedIndexChanged wird aufgerufen:
    2. Private Sub cb_Drives_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cb_Drives.SelectedIndexChanged 'Wird aufgerufen
    3. SelectedDrive = GetDriveByName(cb_Drives.SelectedItem) 'Die Line auch noch (Springt dann zum Event (Sub WndProc), kommt nicht mehr zurück)
    4. System.Diagnostics.Debugger.Break() 'Hier kommt er nicht mehr hin
    5. lbl_VolumeLabel_Anzeige.Text = _SelectedDrive.VolumeLabel
    6. lbl_Freier_Speicher_Anzeige.Text = ConvertByteScale(_SelectedDrive.AvailableFreeSpace)
    7. End Sub
    8. Protected Overrides Sub WndProc(ByRef msg As Message)
    9. 'gibt die OriginalMessage an übergebenes Handles weiter
    10. MyBase.WndProc(msg)
    11. 'Event für externe Auswertung der Message
    12. RaiseEvent WinProc(Me, msg)
    13. 'Wenn ein Laufwerk gewechselt und ein neues Laufwerk erkannt wurde
    14. If msg.Msg = WM_DEVICECHANGE AndAlso msg.WParam = CType(DBT_DEVICEARRIVAL, IntPtr) Then
    15. ...
    16. End If
    17. 'Wenn ein Laufwerk gewechselt und ein Laufwerk entfernt wurde
    18. If msg.Msg = WM_DEVICECHANGE AndAlso msg.WParam = CType(DBT_DEVICEREMOVECOMPLETE, IntPtr) Then
    19. ...
    20. End If
    21. End Sub
    Protected Overrides Sub WndProc(ByRef msg As Message) Ist von HIER (Autor mikeb69)

    Kann mir wer sagen warum cb_Drives_SelectedIndexChanged nie komplett durchlaufen wird?
    Hi
    was für ein Ereignis ist das, führt es Application.Run aus oder blockiert den Thread? Läuft die Anwendung weiter? Ggf. auch durch verschachtelte Invoke-Aufrufe bzw. Synclock auf einem Objekt und ein Invoke-Aufruf unter Verwendung des synchronisierten Objekts?
    Von der Architektur her wär's btw. schöner, über einen IMessageFilter auf Application zu arbeiten.

    Gruß
    ~blaze~
    Er springt von SelectedDrive = GetDriveByName(cb_Drives.SelectedItem)

    In den Sub WndProc(ByRef msg As Message)

    Dort kann ich Minuten lang auf der F11 (Einzelschritt) hängen bleiben und er durchleuft immer und immer wieder WndProc().
    Der Thread wird nichtblockiert, wenn ich F5 (Weiter) drücke kann ich ganz normal mit der Form arbeiten.




    Ok ich hab nen Fehler gemacht, ich verwende die Klasse von Vatter:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.IO
    2. Public Class ClsDrivewatcher
    3. Inherits System.Windows.Forms.NativeWindow
    4. 'Konstanten für Windowsmessages
    5. Private Const WM_DEVICECHANGE As Integer = &H219
    6. Private Const DBT_DEVICEARRIVAL As Integer = &H8000
    7. Private Const DBT_DEVICEREMOVECOMPLETE As Integer = &H8004
    8. 'Events
    9. Public Event WinProc(ByVal sender As ClsDrivewatcher, ByRef m As Message)
    10. Public Event Drive_Neu(ByVal DI As DriveInfo)
    11. Public Event Drive_entfernt(ByVal DN As String)
    12. Private allDrives As New List(Of DriveInfo)
    13. Public Sub New(ByVal Handle As IntPtr)
    14. 'übergibt dem NativeWindow das Handle
    15. MyBase.AssignHandle(Handle)
    16. 'Listet alle Laufwerke in allDrives
    17. allDrives = GetAllDrives()
    18. End Sub
    19. 'Ausgabemöglichkeit für Laufwerkliste
    20. Public Function Getdrives() As List(Of DriveInfo)
    21. Return allDrives
    22. End Function
    23. 'WinProc-Methode des übergebenen Handles
    24. Protected Overrides Sub WndProc(ByRef msg As Message)
    25. 'gibt die OriginalMessage an übergebenes Handles weiter
    26. MyBase.WndProc(msg)
    27. 'Event für externe Auswertung der Message
    28. RaiseEvent WinProc(Me, msg)
    29. 'Wenn ein Laufwerk gewechselt und ein neues Laufwerk erkannt wurde
    30. If msg.Msg = WM_DEVICECHANGE AndAlso msg.WParam = CType(DBT_DEVICEARRIVAL, IntPtr) Then
    31. 'alle laufwerke durchlaufen und in der liste suchen
    32. For Each s As String In Directory.GetLogicalDrives
    33. find_driveinfo_arg = s
    34. Dim d As DriveInfo = allDrives.Find(AddressOf find_driveinfo)
    35. If d Is Nothing Then
    36. d = New DriveInfo(s)
    37. 'laufwerk wurde in der liste nicht gefunden und ist somit neu
    38. 'MessageBox.Show("Neuer Datenträger erkannt = " & d.Name)
    39. 'laufwerk jetzt zur liste hinzufügen
    40. allDrives.Add(d)
    41. 'Event auslösen
    42. RaiseEvent Drive_Neu(d)
    43. End If
    44. Next
    45. End If
    46. 'Wenn ein Laufwerk gewechselt und ein Laufwerk entfernt wurde
    47. If msg.Msg = WM_DEVICECHANGE AndAlso msg.WParam = CType(DBT_DEVICEREMOVECOMPLETE, IntPtr) Then
    48. 'alle laufwerke aus der liste prüfen
    49. Dim temp As List(Of DriveInfo) = GetAllDrives()
    50. For Each d As DriveInfo In allDrives
    51. find_driveinfo_arg = d.Name
    52. Dim lost As DriveInfo = temp.Find(AddressOf find_driveinfo)
    53. If lost Is Nothing Then
    54. 'laufwerk wurde in der liste nicht mehr gefunden
    55. 'MessageBox.Show("Datenträger wurde entfernt = " & d.Name)
    56. 'Event auslösen
    57. RaiseEvent Drive_entfernt(d.Name)
    58. 'laufwerk aus der liste entfernen
    59. allDrives.Remove(d)
    60. 'schleife verlassen
    61. Exit For
    62. End If
    63. Next
    64. End If
    65. End Sub
    66. 'Funktion zum Auflisten der Laufwerke
    67. Private Function GetAllDrives() As List(Of DriveInfo)
    68. Dim ret As New List(Of DriveInfo)
    69. 'und wieder befüllen
    70. For Each d As String In Directory.GetLogicalDrives
    71. ret.Add(New DriveInfo(d))
    72. Next
    73. Return ret
    74. End Function
    75. 'suchfunktion zum finden der laufwerke in der collection
    76. Private find_driveinfo_arg As String
    77. Private Function find_driveinfo(ByVal d As DriveInfo) As Boolean
    78. If d.Name = find_driveinfo_arg Then
    79. Return True
    80. Else
    81. Return False
    82. End If
    83. End Function
    84. End Class


    Also:

    VB.NET-Quellcode

    1. 'WinProc-Methode des übergebenen Handles
    2. Protected Overrides Sub WndProc(ByRef msg As Message)
    3. 'gibt die OriginalMessage an übergebenes Handles weiter
    4. MyBase.WndProc(msg)
    5. 'Event für externe Auswertung der Message
    6. RaiseEvent WinProc(Me, msg)
    7. 'Wenn ein Laufwerk gewechselt und ein neues Laufwerk erkannt wurde
    8. If msg.Msg = WM_DEVICECHANGE AndAlso msg.WParam = CType(DBT_DEVICEARRIVAL, IntPtr) Then
    9. ...
    10. End If
    11. 'Wenn ein Laufwerk gewechselt und ein Laufwerk entfernt wurde
    12. If msg.Msg = WM_DEVICECHANGE AndAlso msg.WParam = CType(DBT_DEVICEREMOVECOMPLETE, IntPtr) Then
    13. ...
    14. End If
    15. End Sub
    Das finde ich nicht gerade schön. Wie wärs, wenn du die ComboBox einfach an eine List(Of DriveInfo) bindest? Dann hättest du direkt die richtigen Objekte und bräuchtest nicht solche blöden Funktionen.
    (Schnell, bevor EDR das schon anmeckert) :D
    @Artentus: Gute Idee! sobald dieses Problem gelöst ist, werde ich eh den ganzen Code überarbeiten müssen weil er einfach nur ranzig geschrieben ist, hatte sogar mal für 2 Minuten checkforillegalcrossthreadcalls = false :rolleyes: ist wieder raus.. glaube an dem Rechner/IDE (nicht meiner) ist sogar Option Strict aus :S , werde das aufjedenfall nochmal prüfen.
    Das mit dem abbrechen des Subs, ist schon echt kurrios ?(
    So Option Strict ist jetzt drinn (hier gleich mal als Standard eingestellt) konnte mit 3 DirectCasts und einen Convert gefixxt werden.

    SelectedDrive ist nach umbau nur noch ein "leeres" Property:

    VB.NET-Quellcode

    1. Private Property SelectedDrive As DriveInfo
    2. Get
    3. Return _SelectedDrive
    4. End Get
    5. Set(ByVal value As DriveInfo)
    6. _SelectedDrive = value
    7. 'lbl_DEBUGSHIT.Text = _SelectedDrive.Name
    8. End Set
    9. End Property


    ErfinderDesRades schrieb:

    ganz normal extrem häufig aufgerufen wird.

    Hab ich ja auch nichts dagegen, nur warum bricht es mein Sub an dieser Stelle ab?
    Ist ja auch nicht so das es immer eine andere Stelle wäre, sondern immer da :(

    Artentus schrieb:

    [...] dann landest du in der WndProc?

    Ja, genau wie ich es oben Kommentiert habe, nach SelectedDrive = GetDriveByName(cb_Drives.SelectedItem) springt er weg.

    @Artentus: Ich werd mal nach der Message suchen, weiß zwar noch nicht wie genau aber ich finds bestimmt.


    VS2010 Ultimate (Legal, MSDN vom Lehrer).


    Wow ich ranz schon so lange Programme auf meine Platte und hatte noch nie solche eine verschluckte Exception, oder ich hab es nicht bemerkt ^^
    Und das obwohl Option Strict On ist.

    Ich werde das mal fixen und hoffe es funktioniert dann, ich geb bescheid :)
    @ErfinderDesRades:
    Combobox nicht Checkbox ^^

    Mit SelectedDrive = GetDriveByName(cb_Drives.SelectedItem.ToString) wird der Fehler nicht mehr geworfen.
    Der Code wird korrekt durchlaufen und es funktioniert.

    Vielen Dank! wurde mal wieder gerettet :D
    Artentus hat recht es ist ein Objekt und GetDriveByName() nimmt einen String entgegen.
    Sobald ich die Fehler weg habe (hab noch 2 andere "Bugs" gefunden) werde ich das mit einer List of Type binden.

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