Keine Rückmeldung trotz Multithreading

  • VB.NET

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von picoflop.

    Keine Rückmeldung trotz Multithreading

    Hi,
    mein Problem ist, dass ich eine Textdatei mit vielen Zeilen einlesen und in eine ListView einfügen will. Damit die Form weiterhin benutzbar bleiben soll, wollte ich das ganze in einem extra Thread machen, jedoch reagiert meine Form trotzdem nicht solange die Textdatei eingelesen wird. Habe es folgendermaßen versucht:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Public path As String
    3. Private Sub btnLoad_Click(...) Handles btnLoad.Click
    4. Dim t As New Threading.Thread(AddressOf LoadAccounts)
    5. path = "..."
    6. t.Start()
    7. End Sub
    8. Delegate Sub addDelegate
    9. Public Sub LoadAccounts()
    10. Dim reader As New IO.StreamReader(path)
    11. Dim currLine, Username, Password As String
    12. If lvAccounts.InvokeRequired Then
    13. Me.Invoke(New addDelegate(AddressOf LoadAccounts))
    14. Else
    15. Do
    16. currLine = reader.ReadLine()
    17. If currLine = Nothing
    18. Exit Do
    19. End If
    20. Username = currLine.Split(":")(0)
    21. Password = currLine.Split(":")(1)
    22. Dim lvItem As ListViewItem = lvAccounts.Items.Add(Username)
    23. lvItem.SubItems.Add(Password)
    24. Loop
    25. End If
    26. End Sub
    27. End Class

    Kann mir jemand sagen was ich falsch gemacht habe?
    Invoke+ häufiger Zugriff auf die GUI lässt diese natürlich auch einfrieren...
    Lad dir deine Items erst in eine Collection um sie anschließend hinzuzufügen(außerhalb des Threads)...
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    ListView-Control vor dem Hinzufügen auf UpdateModus (BeginUpdate) wechseln und danach den UpdateModus wieder mit EndUpdate beenden. Das bringt einiges an Performance. Beispiel:

    VB.NET-Quellcode

    1. With ListView1
    2. Try
    3. .BeginUpdate() ' Updatemodus einschalten
    4. For Each value As String In values
    5. .Items.Add(New ListViewItem(value.Split(";"c)))
    6. Next
    7. Catch ex As Exception
    8. ' Fehlerbehandlung
    9. Finally
    10. .EndUpdate() ' Updatemodus ausschalten!
    11. End Try
    12. End With
    Zum ursprünglichen Problem:
    WENN InvokeRequired, ruft sich die Funktion nochmal selbst auf, aber dann im Context des UI Threads. Mit anderen Worten, das Multithreading ist komplett unnötig, da es eh nie zum Tragen kommt.

    UI Thread -> anderer Thread -> UI Thread !

    WENN schon Multithreading/Asynchron, dann die "Arbeit" auslagern und im UI Thread dann nur noch das "Ergebnis" zuweisen. Für sowas bietet sich dann das Async CTP an ;)