Multithreading, Steuerelemente Threadsicher machen

  • VB.NET

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

    Multithreading, Steuerelemente Threadsicher machen

    Hallo, ich bin nicht nur ganz neu hier im Forum sondern auch noch recht unerfahren in Sachen VB.

    Ich habe bereits ein paar Kleinigkeiten geschrieben und stehe jetzt aber vor dem Problem das ich einen Kopiervorgang in einen extra Thread packen muss damit die Form nutzbar bleibt.
    Allerdings ist es mir bisher nicht so recht gelungen vom Thread des Kopiervorganges auf die Steuerelemente im Thread der Form zuzugreifen.

    Ich habe hier mal einen kleinen Teil des Kopiervorganges eingefügt.

    VB.NET-Quellcode

    1. If CheckBoxAktiv1.Checked Then
    2. With ListView1.Items.Add("Mod: " & modname1 & " wird installiert.")
    3. .ForeColor = Color.Blue
    4. End With
    5. ListView1.Refresh()
    6. Try
    7. CopyFolder(modfolder1, wotfolderpath & "\res_mods\" & _version)
    8. CheckBoxAktiv1.Checked = False
    9. mod1aktiv = True
    10. My.Settings.mod1aktiv = mod1aktiv
    11. My.Settings.Save()
    12. LabelAktiv1.ForeColor = Color.Green
    13. LabelAktiv1.Text = "On"
    14. With ListView1.Items.Add("Mod: " & modname1 & " erfolgreich installiert!")
    15. .ForeColor = Color.Green
    16. End With
    17. ListView1.Refresh()
    18. ProgressBar1.Value += aktivmods
    19. ProgressBar1.Refresh()
    20. Catch es As Exception
    21. With ListView1.Items.Add("Mod: " & modname1 & " Installation fehlgeschlagen!")
    22. .ForeColor = Color.Red
    23. End With
    24. ListView1.Refresh()
    25. MsgBox(es.Message.ToString)
    26. End Try
    27. End If


    Das am Code noch was zu verbessern ist weis ich.
    Mein Problem liegt jetzt aber dabei, das ich nicht so recht weis wie ich auf die Steuerelemente zugreife kann.
    Diesen Code in einen extra Thread zu packen bekomme ich noch hin, aber mit dem ganzen invoke komme ich nicht klar.

    Kann mir vielleicht jemand verständlich erklären wie ich das am oberen Beispiel machen kann?
    Also: Wenn du aus einem extra Thread auf die Steuerelemente zugreifen willst, musst du dass in dem Thread von den Steuerelementen machen. Da Me in dem Thread der Steuerelemente ist schreiben die meisten Me.BeginInvoke.... Du kannst aber auch zB. Button1.BeginInvoke... schreiben, dass wäre ungefähr das gleiche, da der Thread der gleiche ist. Das heißt: Aus einem anderen Thread kannst du auf den Hauptthread zugreifen mit IrgendetwasAusDemHauptthread.BeginInvoke(Sub() 'Deine Aktion, zB. Button1.Text = "Hallo")


    Vielleicht sollte ich noch sagen: Wenn du viel auf einmal ändern willst, kannst du auch:

    VB.NET-Quellcode

    1. Me.BeginInvoke(Sub()
    2. 'MachWas
    3. 'Button1.Text = "Hallo"
    4. 'Button2.Enable = False
    5. End Sub)

    schreiben.

    Eine Erläuterung zum Unterschied zwischen Invoke und BeginInvoke (bei Controls!)
    • Invoke = Es wird gewartet, bis die Aktion ausgeführt wurde
    • BeginInvoke = Es wird einfach weitergemacht

    Auf Deutsch:
    Mit Invoke warten wir auf die Person, die für uns ins Handschuhfach greift. Dadurch wird der Thread aufgehalten. Bei BeginInvoke sagen wir einfach nur, dass unser Helfer ins Handschuhfach greifen soll und machen weiter ohne zu warten.
    Mfg
    Vincent

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

    Beispiel eines KFZ: wenn du im Auto sitzt, kannst du bequem ins Handschuhfach greifen. Wenn du neben dem Auto stehst, solltest du das tunlichst vermeiden, wenn wenn das Auto fährt, während du durchs Fenster ins Auto greifst, wird es filmreif.
    Das Schlüsselwort "Invoke" hast du ja schon. Damit forderst du - unser KFZ-Beispiel vorausgesetzt - jemanden im Inneren des Fahrzeuges auf, für dich ins Handschuhfach zu greifen.

    Im erstellten THREAD:

    VB.NET-Quellcode

    1. Me.Invoke(Sub() Me.Backcolor=Color.Yellow)
    Entweder das was Kurt gesagt hat oder Du nimmst asynchrone Invokes.

    Beispiel anhand von einem ListViewitem:


    VB.NET-Quellcode

    1. Dim D As Action = Sub()
    2. ListView1.BeginInvoke(Sub()
    3. Dim m(0) As Object
    4. m(0) = "Test"
    5. ListViewItemz.Add(CType(m(0), ListViewItem))
    6. End Sub)
    7. End Sub)
    8. D.BeginInvoke(AddressOf D.EndInvoke, Nothing)


    You will love it ..

    VincentTB schrieb:

    Also: Wenn du aus einem extra Thread auf die Steuerelemente zugreifen willst, musst du dass in dem Thread von den Steuerelementen machen. Da Me in dem Thread der Steuerelemente ist schreiben die meisten Me.BeginInvoke.... Du kannst aber auch zB. Button1.BeginInvoke... schreiben, dass wäre ungefähr das gleiche, da der Thread der gleiche ist. Das heißt: Aus einem anderen Thread kannst du auf den Hauptthread zugreifen mit IrgendetwasAusDemHauptthread.BeginInvoke(Sub() 'Deine Aktion, zB. Button1.Text = "Hallo")


    Vielleicht sollte ich noch sagen: Wenn du viel auf einmal ändern willst, kannst du auch:

    VB.NET-Quellcode

    1. Me.BeginInvoke(Sub()
    2. 'MachWas
    3. 'Button1.Text = "Hallo"
    4. 'Button2.Enable = False
    5. End Sub)

    schreiben.

    Eine Erläuterung zum Unterschied zwischen Invoke und BeginInvoke (bei Controls!)
    • Invoke = Es wird gewartet, bis die Aktion ausgeführt wurde
    • BeginInvoke = Es wird einfach weitergemacht

    Auf Deutsch:
    Mit Invoke warten wir auf die Person, die für uns ins Handschuhfach greift. Dadurch wird der Thread aufgehalten. Bei BeginInvoke sagen wir einfach nur, dass unser Helfer ins Handschuhfach greifen soll und machen weiter ohne zu warten.

    Funktioniert ja wirklich erste Sahne :thumbup: , mit so einem spitzen Tipp hätte ich nie gerechnet.
    Wenn ich alles auf Multithreading umgeschrieben habe werde ich mich gern erkenntlich zeigen in form einer kleinen Spende . :)