Buho1
Member
This is my first excursion into multithreading.
Winforms VB.NET 4.0. I want to launch about 300 threads that calculate a result, and I want these 300 results displayed in the main form, results shown as they come in.
I initially wrote this, which makes sense to me:
It compiles, but the only result in ListBox1 is "Task 20 - 400". I modified the above code to launch just 2 threads, and when they are handled one at a time, launch one more, leaving off where a global counter was set.
This worked better, ListBox1 displayed Task 1, Task 2, and Task 3, but still Task 0 was not shown - the initial thread I started.
Debugging this code, it is clear that
From my initial For loop, all threads are started and processed and they all raise events, but only the last thread in that loop is handled! What's going on?! Am I not understanding something fundamental? The code above is reproducible - try it yourself.
Winforms VB.NET 4.0. I want to launch about 300 threads that calculate a result, and I want these 300 results displayed in the main form, results shown as they come in.
I initially wrote this, which makes sense to me:
VB.NET:
Imports System.Threading
Public Class MyTask
Public UID As String
Public Num As Integer
Public Result As Integer
Public Event ThreadComplete(ByVal ThreadPayload As Tuple(Of String, Integer))
Public Sub New(ByVal _uid As String, ByVal _num As Integer)
UID = _uid
Num = _num
Result = 0
End Sub
Public Function Square(ByVal _num As Integer) As Integer
Return _num * _num
End Function
Public Sub BackgroundProcess()
Result = Square(Num)
RaiseEvent ThreadComplete(New Tuple(Of String, Integer)(UID, Result))
End Sub
End Class
Public Class Form1
Private WithEvents oMyTask As MyTask
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
For x As Integer = 0 To 20
oMyTask = New MyTask("Task " + x.ToString(), x)
Dim t As New Thread(AddressOf oMyTask.BackgroundProcess)
t.Start()
Next
End Sub
Private Sub displayResult(ByVal ThreadPayload As Tuple(Of String, Integer)) Handles oMyTask.ThreadComplete
Me.ListBox1.Items.Add(ThreadPayload.Item1 + " - " + ThreadPayload.Item2.ToString())
End Sub
End Class
VB.NET:
Public Class Form1
Private WithEvents oMyTask As MyTask
Private threadLastMade As Integer
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
For x As Integer = 0 To 1
launchThread(x)
Next
End Sub
Private Sub launchThread(ByVal x As Integer)
oMyTask = New MyTask("Task " + x.ToString(), x)
Dim t As New Thread(AddressOf oMyTask.BackgroundProcess)
t.Start()
threadLastMade = x
End Sub
Private Sub displayResult(ByVal ThreadPayload As Tuple(Of String, Integer)) Handles oMyTask.ThreadComplete
Me.ListBox1.Items.Add(ThreadPayload.Item1 + " - " + ThreadPayload.Item2.ToString())
If threadLastMade < 3 Then launchThread(threadLastMade + 1)
End Sub
End Class
This worked better, ListBox1 displayed Task 1, Task 2, and Task 3, but still Task 0 was not shown - the initial thread I started.
Debugging this code, it is clear that
- the initial threads are started,
- the initial threads are processed and ThreadComplete is raised,
- but only the last of the initial threads is handled by displayResult!
From my initial For loop, all threads are started and processed and they all raise events, but only the last thread in that loop is handled! What's going on?! Am I not understanding something fundamental? The code above is reproducible - try it yourself.