Trotz Backgroundworker Async "friert" Programm

  • VB.NET

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von VaporiZed.

    Trotz Backgroundworker Async "friert" Programm

    Hallo,

    Ich frage in meinem Programm alle 10 Sekunden (Timer) den Status von Netzwerkkarten/Adapter ab.
    Nun ist jedoch das Problem, dass seitdem ich die zweite Schleife ("For Each adapter...") in meinen Backgroundworker eingebaut habe, mein Programm einfriert für längere Zeit..
    Wenn ich die zweite Schleife rausnehme, arbeitet es komplett normal. Auch kann funktioniert die zweite Schleife, wenn ich den Code in einem Button auslagere und per Klick ausführe...
    Es gibt daher eigentlich keinen Fehler oder ähnliches. Ich hatte es auch schon über 2 Timer und 2 Backgroundworkern versucht. Jedoch friert es immer ein, sobald der Teil "For Each adapter...") im Backgroundworker abgearbeitet wird.
    Woran liegt das?


    Quellcode

    1. ​Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
    2. RichTextBox.Clear()
    3. BackgroundWorker1.RunWorkerAsync()
    4. Timer2.Enabled = False
    5. End Sub
    6. Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    7. Try
    8. Dim PrimaryNic As New Collection
    9. Dim PNic As String = ""
    10. For Each networkCard As NetworkInterface In NetworkInterface.GetAllNetworkInterfaces
    11. Dim IpAddress As UnicastIPAddressInformation
    12. For Each IpAddress In networkCard.GetIPProperties.UnicastAddresses
    13. RichTextBox.AppendText("IP Addresse : " & IpAddress.Address.ToString & vbCrLf)
    14. RichTextBox.AppendText("Subnetmask : " & IpAddress.IPv4Mask.ToString & vbCrLf)
    15. Next
    16. For Each gatewayAddr As GatewayIPAddressInformation In networkCard.GetIPProperties.GatewayAddresses
    17. ' Get IP gateway information
    18. RichTextBox.AppendText("Gateway : " & gatewayAddr.Address.ToString & vbCrLf)
    19. Next
    20. Next
    21. For Each adapter In System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()
    22. If adapter.OperationalStatus = Net.NetworkInformation.OperationalStatus.Up Then
    23. If adapter.Name = "LAN1" Then
    24. '...
    25. End If
    26. If adapter.Name = "LAN2" Then
    27. '...
    28. End If
    29. If adapter.Name = "LAN3" Then
    30. '...
    31. End If
    32. Else
    33. End If
    34. Next
    35. Catch ex As Exception
    36. MsgBox("Fehler")
    37. End Try
    38. End Sub
    39. Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1RunWorkerCompleted
    40. Timer2.Enabled = True
    41. End Sub
    Erstmal würde ich sagen mach das komische Try-Catch weg denn es hilft dir null falls es zu Fehlern kommt.
    siehe dazu: TryCatch ist ein heißes Eisen

    Warum gehst du denn 2x alles durch?
    Denn For Each networkCard As NetworkInterface In NetworkInterface.GetAllNetworkInterfaces
    ist das gleiche wie: For Each adapter In System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()

    Also mach das doch alles in einer For Each.

    Greifst du villt in der 2. For Each noch auf irgendwelche GUI Elemente zu und hast sogar "CheckForIllegalCrossThreadCalls" ( docs.microsoft.com/de-de/dotne…s?view=netframework-4.7.2 )
    auf false?
    Grüße , xChRoNiKx

    Nützliche Links:
    Visual Studio Empfohlene Einstellungen | Try-Catch heißes Eisen
    Ich hab den Code mal bei mir getestet. Da kommt erstmal ein ganz netter Spruch:

    Und warum siehst Du das nicht? Weil mal wieder Try-Catch ohne Sinn und Verstand genutzt wird.

    btw: nimm mal bitte nicht die allgemeinen <>-CodeTags, sondern die VB.Net-CodeTags

    oh, da war wohl jemand schneller ^^

    ##########

    Wann stirbt eigentlich der BGW endlich aus. Aktueller Stand der Dinge ist Async/Await.
    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.

    zauber777 schrieb:

    Nein ich greife nicht auf irgendwelche weiteren GUI Elemente zu.
    Auf weitere nicht. Aber eins reicht schon, um den Fehler zu machen. Du sagst es ja auch selber:

    zauber777 schrieb:

    Ich fülle eine Richtextbox
    in einem nebenläufigen (asynchronen) Teil Deines Codes. Das ist nun mal nicht erlaubt, erzeugt eine Exception und ist ein no-go. Entferne das Try-Catch und Du wirst die in meinem Screenshot angegebene Fehlermeldung bekommen, wenn Du nicht CheckForIllegalCrossThreadCalls = False hast (und Du solltest dieses CheckForIllegalCrossThreadCalls auch niemals auf False haben.)
    Eine gute Alternative wäre, wenn Du stattdessen eine List(Of String) mit Deinen Namen befüllst, die dann im BackgroundWorker1_RunWorkerCompleted-EventHandler in die RTB gefüllt wird.
    Für alle, die die Invoke-Idee haben: Ich wär dagegen, es geht auch ohne.
    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.
    Wie schon vorher geschrieben mach das Try-Catch weg und löse erstmal die Fehler die kommen.
    Also z.b. CheckForIllegalCrossThreadCalls nicht auf false stellen, die GUI Updates evtl. am Ende des Backgroundworkers machen
    (gibt da nen RunWorkerCompleted Event). Oder du machst es gleich wie @VaporiZed geschrieben hat mit Async/Await ordentlich.

    Aber wichtig ist vor allem mal das Try-Catch weg zumachen und dir dann die Fehler anschauen die kommen.


    //EDIT: da war wohl @VaporiZed dieses mal schneller als ich :P
    Grüße , xChRoNiKx

    Nützliche Links:
    Visual Studio Empfohlene Einstellungen | Try-Catch heißes Eisen
    Ich glaube da fehlt mir etwas Hintergrundwissen um alles zuverstehen, wie ihr es meint...
    Try-Catch habe ich entfernt - bekomme keine Fehlermeldung (habe auch Option Strict on, nur falls das als Frage kommt...).
    Zu den CheckForIllegalCrossThreadCalls kann ich nicht viel sagen, aber da ich denke, dass diese Standardmäßig schon true und ich nichts daran geändert habe, wird dies so richtig sein.

    Denn For Each networkCard As NetworkInterface In NetworkInterface.GetAllNetworkInterfaces ist das gleiche wie: For Each adapter In System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()

    habe ich nun zusammengefasst.
    Die Richtextbox wird weiterhin gefüllt, aber danach friert es wieder ein...

    VB.NET-Quellcode

    1. Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
    2. RichTextBox.Clear()
    3. BackgroundWorker1.RunWorkerAsync()
    4. Timer2.Enabled = False
    5. End Sub
    6. Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    7. Label1.Text = "LAN-1 ist nicht aktiviert"
    8. Label2.Text = "LAN-2 ist nicht aktiviert"
    9. Label3.Text = "LAN-3 ist nicht aktiviert"
    10. For Each adapter In System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()
    11. If adapter.OperationalStatus = Net.NetworkInformation.OperationalStatus.Up Then
    12. If adapter.Name = "LAN1" Then
    13. Label1.Text = "LAN-1 ist aktiviert"
    14. End If
    15. If adapter.Name = "LAN-2" Then
    16. Label2.Text = "LAN-2 ist aktiviert"
    17. End If
    18. If adapter.Name = "LAN-3" Then
    19. Label3.Text = "LAN-3 ist aktiviert"
    20. End If
    21. Else
    22. End If
    23. Dim IpAddress As UnicastIPAddressInformation
    24. For Each IpAddress In adapter.GetIPProperties.UnicastAddresses
    25. RichTextBox1.AppendText("IP Addresse : " & IpAddress.Address.ToString & vbCrLf)
    26. RichTextBox1.AppendText("Subnetmask : " & IpAddress.IPv4Mask.ToString & vbCrLf)
    27. Next
    28. For Each gatewayAddr As System.Net.NetworkInformation.GatewayIPAddressInformation In adapter.GetIPProperties.GatewayAddresses
    29. ' Get IP gateway information
    30. RichTextBox1.AppendText("Gateway : " & gatewayAddr.Address.ToString & vbCrLf)
    31. Next
    32. Next
    33. End Sub
    34. Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
    35. Timer2.Enabled = True
    36. End Sub[


    Ich bekomme keine Fehlermeldungen... Aber die Label1 bis 3 werden auch nicht geändert.
    Eigentlich bin ich immer mit BackGroundWorkern sehr gut zurecht gekommen. Aber nun verzweifel ich einfach.

    Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „zauber777“ ()

    zauber777 schrieb:

    Try-Catch habe ich entfernt - bekomme keine Fehlermeldung
    Dann stellt sich die Frage, warum Du es drinhattest.

    zauber777 schrieb:

    Zu den CheckForIllegalCrossThreadCalls kann ich nicht viel sagen, aber da ich denke, dass diese Standardmäßig schon true und ich nichts daran geändert habe, wird dies so richtig sein.
    Ja, das ist richtig, standardmäßig ist CheckForIllegalCrossThreadCalls bei True, aber ich habe Deinen Code bei mir reinkopiert und es kommt die zu erwartende Exception von Post#3. Lies mal bitte CheckForIllegalCrossThreadCalls aus und schau, welchen Wert es hat.

    Und nochmal: Nutze bitte die VB.Net-CodeTags. Sowas ist unschön:

    Quellcode

    1. Public Sub Test()

    so ist es mit den VB-Tags für uns besser zu lesen:

    VB.NET-Quellcode

    1. Public Sub Test()

    Guckst Du hier für weitere Infos zum Thema CodeTags.
    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.
    Ich habe jetzt ein komplett neues Projekt erstellt und nur den Code reinkopiert. Es kommt weiterhin nirgends die genannte Fehlermeldung...
    "CheckForIllegalCrossThreadCalls" kann ich nirgends finden ;(

    Update :
    In einem komplett neuen Projekt funktioniert auch alles ohne einzufrieren.... nun versteh ich nichts mehr.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „zauber777“ ()

    Probier mal folgendes Projekt. Es muss eine Fehlermeldung geben, wenn Du den Button klickst.

    Ich nutze Visual Studio 2017 und 2019, .Net Framework 4.6.1
    Dateien
    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.
    Auch in deinem Projekt wird bei mir kein Fehler angezeigt, wenn ich meinen Code hinein kopiere...
    Ich benutze Visual Studio Professional 2013 mit Net 4.7

    Ich glaube nun aber den Fehler gefunden zuhaben.
    In der Abfrage der Adapter lade ich zusätzlich Pictureboxen, bzw. schalte ich diese visible oder auch nicht.
    In den Pictureboxen habe ich jedoch keine JPG oder BMP drin, sondern ICO. (soll LED´s darstellen - rot und grün)
    Vielleicht ist dies das Problem!?
    Au au. Wenn noch nicht mal ein Fehler bei meinem Projekt erzeugt wird, dann sind wohl die Exception-Meldungen in Deinem VS falsch eingestellt. Das ist derb.
    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.