Hallo Leute,
nachdem ich mich im Internet in das Thema "Multi-Threading in VB.NET" eingelesen habe, dachte ich mir, erstelle ich mal ein kleines Testprogramm, um zu schauen, wie das funktioniert. Das Testprogramm soll einfach nur ein Formular mit zwei Listboxen öffnen, zwei Threads sollen in je einer der Listboxen Messages ausgeben (und damit lang laufende parallele Verarbeitungen simulieren, die Fortschrittsmeldungen bringen) und nachdem beide Threads abgearbeitet sind, soll eine Messagebox erscheinen, die das Ergebnis beider Threads anzeigt.
Dazu habe ich eine Testklasse erstellt, die die lang laufende Verarbeitung simuliert:
Das Formular mit den zwei Listboxen hat folgenden Code. Die zwei Prozeduren entsprechen sich, sprechen halt nur jeweils die andere Listbox an:
Und schließlich und endlich der Code, der beides ansteuert:
Wenn ich im letzten Code-Abschnitt die Konstante "MULTI_THREAD" auf "False" stelle, funktioniert alles, aber eben sequentiell. Stelle ich sie hingegen auf "True", wird zwar das Formular angezeigt aber es dreht sich eine Sanduhr und es passiert sonst nichts, keine Fortschrittsmeldungen und kein Ergebnis.
Kann mir jemand sagen, was ich hier falsch mache? Ich habe es auch schon mit normalen Threads (statt der in Framework 4.0 neuen Tasks) bzw. mit Delegates und den dortigen "BeginInvoke" und "EndInvoke" probiert, das Ergebnis blieb aber im Großen und Ganzen dasselbe (keine Fortschrittsanzeige).
Vielen Dank im Voraus für die Hilfe, mittlerweile weiß ich echt nicht mehr, was ich noch ausprobieren soll.
nachdem ich mich im Internet in das Thema "Multi-Threading in VB.NET" eingelesen habe, dachte ich mir, erstelle ich mal ein kleines Testprogramm, um zu schauen, wie das funktioniert. Das Testprogramm soll einfach nur ein Formular mit zwei Listboxen öffnen, zwei Threads sollen in je einer der Listboxen Messages ausgeben (und damit lang laufende parallele Verarbeitungen simulieren, die Fortschrittsmeldungen bringen) und nachdem beide Threads abgearbeitet sind, soll eine Messagebox erscheinen, die das Ergebnis beider Threads anzeigt.
Dazu habe ich eine Testklasse erstellt, die die lang laufende Verarbeitung simuliert:
Code:
Imports System.Threading Public Class TestClass Public Event ShowProgress(ByVal message As String) Private _milliSeconds As UShort Public Sub New(milliSeconds As UShort) _milliSeconds = milliSeconds End Sub Public Function Run() As UShort For i As Integer = 1 To 20 RaiseEvent ShowProgress("Run " & i) Thread.Sleep(_milliSeconds) Next i Return _milliSeconds End Function End Class
Code:
Public Delegate Sub ShowProgressDelegate(ByVal message As String) Public Class Form1 Public Sub AddMessage1(ByVal message As String) If String.IsNullOrEmpty(message) Then Exit Sub End If If Me.InvokeRequired Then Me.Invoke(New ShowProgressDelegate(AddressOf Me.AddMessage1), New Object() {message}) Else Me.ListBox1.Items.Add(message) Me.ListBox1.SelectedIndex = Me.ListBox1.Items.Count - 1 Application.DoEvents() End If End Sub Public Sub AddMessage2(ByVal message As String) If String.IsNullOrEmpty(message) Then Exit Sub End If If Me.InvokeRequired Then Me.Invoke(New ShowProgressDelegate(AddressOf Me.AddMessage2), New Object() {message}) Else Me.ListBox2.Items.Add(message) Me.ListBox2.SelectedIndex = Me.ListBox2.Items.Count - 1 Application.DoEvents() End If End Sub End Class
Code:
Imports System.Threading.Tasks Public Class Start Private Const MULTI_THREAD As Boolean = False Public Shared Sub Main() Dim test1 As TestClass Dim test2 As TestClass Dim task1 As Task(Of UShort) Dim task2 As Task(Of UShort) Dim result1 As UShort Dim result2 As UShort test1 = New TestClass(50) test2 = New TestClass(100) Using frm As Form1 = New Form1 frm.Show() AddHandler test1.ShowProgress, AddressOf frm.AddMessage1 AddHandler test2.ShowProgress, AddressOf frm.AddMessage2 If MULTI_THREAD Then task1 = Task(Of UShort).Factory.StartNew(Function() test1.Run) task2 = Task(Of UShort).Factory.StartNew(Function() test2.Run) Task.WaitAll(task1, task2) result1 = task1.Result result2 = task2.Result Else result1 = test1.Run result2 = test2.Run End If RemoveHandler test1.ShowProgress, AddressOf frm.AddMessage1 RemoveHandler test2.ShowProgress, AddressOf frm.AddMessage2 frm.Close() End Using MessageBox.Show("Result 1: " & result1 & "; Result 2: " & result2) End Sub End Class
Kann mir jemand sagen, was ich hier falsch mache? Ich habe es auch schon mit normalen Threads (statt der in Framework 4.0 neuen Tasks) bzw. mit Delegates und den dortigen "BeginInvoke" und "EndInvoke" probiert, das Ergebnis blieb aber im Großen und Ganzen dasselbe (keine Fortschrittsanzeige).
Vielen Dank im Voraus für die Hilfe, mittlerweile weiß ich echt nicht mehr, was ich noch ausprobieren soll.
Comment