1

I'm making a simple multithreading program to explain the working of threading. I want two counters counting on the same time but it doesn't work.

It only works if I use: CheckForIllegalCrossThreadCalls = False. But, I want to program in a proper way.

Code:

Dim Thread1 As System.Threading.Thread Dim Thread2 As System.Threading.Thread Private Delegate Sub SetTeller1() Private Sub teller1() If teller1Label.InvokeRequired Then Invoke(New SetTeller1(AddressOf teller1)) Else For i As Integer = 0 To 1000 teller1Label.Text = i Refresh() Next End If End Sub Delegate Sub SetTeller2() Private Sub teller2() If teller2Label.InvokeRequired Then Invoke(New SetTeller2(AddressOf teller2)) Else For i As Integer = 0 To 1000 teller2Label.Text = i Refresh() Next End If End Sub Private Sub teller1Button_Click(sender As Object, e As EventArgs) Handles teller1Button.Click Thread1 = New Threading.Thread(AddressOf teller1) Thread1.Start() End Sub Private Sub teller2Button_Click(sender As Object, e As EventArgs) Handles teller2Button.Click Thread2 = New Threading.Thread(AddressOf teller2) Thread2.Start() End Sub 

1 Answer 1

2

The multithreading works perfectly, but you are not utilizing it. The only thing you're currently doing in the background thread is calling Invoke, which means that your thread will exit within a few milliseconds and then be discarded.

Once you call Invoke the execution of the teller1 or teller2 method is moved to the UI thread, meaning it will block the UI until its execution is finished. You should only invoke when you are to update the UI, and perform all iterations in the background thread.

Here's an example of how you can do it more properly:

Delegate Sub SetTeller1(ByVal Text As String) Private Sub teller1() For i As Integer = 0 To 1000 SetTeller1Text(i) Next End Sub Private Sub SetTeller1Text(ByVal Text As String) If Me.InvokeRequired Then Me.Invoke(New SetTeller1(AddressOf SetTeller1Text), Text) Else teller1Label.Text = Text Me.Refresh() End If End Sub 

For improved readability I changed for example Invoke(...) to Me.Invoke(...).

Also I'm not sure why you're calling Refresh() as it isn't necessary and will just cause extra redrawing of the entire container (guessing this is a form).

Sign up to request clarification or add additional context in comments.

Comments