Multithreading

    • VB.NET

    Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von Eisfuchs.

      Multithreading

      Hi,

      ihr kennt doch das Problem: Wenn ihr lange Vorgänge in euren Programmen ausführt, wird das Programm instabil oder stürzt ab.
      Die Lösung: Ihr lasst den Vorgang auf einem anderen Thread ausführen. Das kann man zum Beispiel mit einem Backgroundworker machen, aber es geht auch ohne:


      Zuerst erstellen wir einen ganz normalen Sub, der den großen Vorgnag ausführen soll, z.B

      VB.NET-Quellcode

      1. Private Sub LangerVorgang()
      2. Dim i As Integer
      3. For i = 1 To 100000
      4. 'irgendwas langes
      5. Next
      6. End Sub


      Wenn man ihn jetzt so ausführt, läuft er auf dem selben Thread und bringt, wenn der Vorgang sehr lange dauert, das Programm zum Absturz. Deswegen müssen wir diesen Sub auf einen neuen Thread verlagern. Für eurem Projekt einen Button (Button1) hinzu uns schreibt in sein Click_Event folgenden Code:

      VB.NET-Quellcode

      1. Dim neuerthread As System.Threading.Thread
      2. neuerthread = New System.Threading.Thread(AddressOf Me.LangerVorgang)
      3. neuerThread.Start() 'Vorgang starten


      Wenn ihr jetzt auf den Button klickt, wird der lange Vorgang auf einem neuen Thread ausgeführt!

      lg julianibus

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

      Hallo
      Und was ist, wenn ich den Vorgang aufrufen will??

      Quellcode

      1. Sub LangerVorgang(ByVal Zahl As Integer, ByVal a As String)
      2. Dim i As Integer
      3. For i = 1 To Zahl
      4. 'irgendwas langes
      5. Next
      6. End Sub


      Bei dem Code:

      Quellcode

      1. Dim neuerthread As System.Threading.Thread
      2. neuerthread = New System.Threading.Thread(AddressOf Me.LangerVorgang)
      3. neuerthread.Start() 'Vorgang starten


      kommt der Fehler:
      Fehler 1 Fehler bei der Überladungsauflösung, da keine zugreifbare "New" mit diesen Argumenten aufgerufen werden kann:
      'Public Sub New(start As System.Threading.ParameterizedThreadStart)': Die Signatur der Public Sub LangerVorgang(Zahl As Integer, a As String)-Methode ist mit dem Delegaten "Delegate Sub ParameterizedThreadStart(obj As Object)" nicht kompatibel.
      'Public Sub New(start As System.Threading.ThreadStart)': Die Signatur der Public Sub LangerVorgang(Zahl As Integer, a As String)-Methode ist mit dem Delegaten "Delegate Sub ThreadStart()" nicht kompatibel. C:\Users\Denny\AppData\Local\Temporary Projects\WindowsApplication1\Form1.vb 5 23 WindowsApplication1
      Dann eben so in die Richtung:

      VB.NET-Quellcode

      1. Public Class Form1
      2. Dim neuerthread As New System.Threading.Thread(AddressOf Start)
      3. Sub LangerVorgang(ByVal Zahl As Integer, ByVal a As String)
      4. Dim i As Integer
      5. Dim gesamt As Integer = 0
      6. For i = 1 To Zahl
      7. gesamt += i
      8. Debug.Print(gesamt)
      9. Next
      10. MsgBox("Fertig!")
      11. End Sub
      12. Sub Start()
      13. LangerVorgang(10000, "bla")
      14. End Sub
      15. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
      16. neuerthread.Start()
      17. End Sub
      18. End Class
      Ich bekomm immer die Meldung:

      Quellcode

      1. Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement ListBox1 erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde.


      Wie ermögliche ich threadübergreifende Zugriffe?
      Mein Code:

      VB.NET-Quellcode

      1. Public Class Form1
      2. Private Sub aList()
      3. Dim i As Integer = 0
      4. For i = i To 100
      5. ListBox1.Items.Add(i)
      6. Next
      7. End Sub
      8. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      9. Dim aList As New System.Threading.Thread(AddressOf Me.aList)
      10. aList.Start() 'Vorgang starten
      11. End Sub
      12. End Class
      ja das Problem hatte ich auch mal, hab dann nach langem suchen die Lösung gefunden:

      VB.NET-Quellcode

      1. Delegate Sub dlgSetAnyListbox(ByVal tb As ListBox, ByVal s As String)
      2. Private Sub SetAnyListbox(ByVal tb As ListBox, ByVal s As String)
      3. tb.Items.Add(s)
      4. tb.Refresh()
      5. End Sub
      6. // Dort wo es aufgrufen werden soll:
      7. Dim d As New dlgSetAnyListbox(AddressOf SetAnyListbox)
      8. // Zum eintragen:
      9. Invoke(d, ListBox1, inhalt)