Question

I am new to multithreading.I googled some basic examples below is the code

Imports System.Threading
Public Class Form1
Dim t As New Thread(AddressOf Me.BackgroundProcess)
Private Sub btnStartThread_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStartThread.Click
    t.Start()
End Sub

Private Sub StopButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StopButton.Click
    t.Abort()
End Sub

Public Sub BackgroundProcess()
    Dim i As Integer = 1

    If Me.InvokeRequired Then
        Me.Invoke(New MethodInvoker(AddressOf BackgroundProcess))
    Else
        Do While True
            Me.ListBox1.Items.Add("Iteration:" & i)
            i += 1
        Loop
    End If
End Sub
End Class

When I click on Start thread my UI becomes unresponsive.What would be the reason behind this.Below is the screenshot of UI Form1

Was it helpful?

Solution

Your code in the "Background" thread checks to see if it is on the UI thread

If Me.InvokeRequired Then

and if not, it tells it to run on the UI thread.

Me.Invoke(New MethodInvoker(AddressOf BackgroundProcess))

If it is on the UI thread, it sits in a loop, blocking the UI thread, without pumping.

Do While True

To get this to work, one of the MANY ways to do it is like this:

Public Delegate Sub AddItemDelegate(ByVal item As Object)
Public Sub BackgroundProcess()
    Dim i As Integer = 1

    Do While True
        i += 1
        If Me.InvokeRequired Then
            Me.Invoke(New AddItemDelegate(AddressOf AddItem), "Iteration:" & i)
         Else
            AddItem("Iteration:" & i)
        End If
    Loop
End Sub
Private Sub AddItem(ByVal item As Object)
    Me.ListBox1.Items.Add(item)
End Sub

Using a delegate is the prefered way.

OTHER TIPS

When running your code the UI is unresponsive because the UI is receiving a vast amount of updates in a very short space of time, either stop the loop from being infinite :

        Do While True
            Me.ListBox1.Items.Add("Iteration:" & i)
            If i > 10 Then
                Exit Do
            End If
            i += 1
        Loop

Or add a wait timer after each loop to slow down the how often the UI is updated :

        Do While True
            Me.ListBox1.Items.Add("Iteration:" & i)
            i += 1
            'Sleep for 1 second
            Thread.CurrentThread.Sleep(1000)
        Loop

Also you should stop the code running on the UI thread as you are currently creating a thread to then run something on the UI thread, which seems un-needed to me.

i.e. change

Me.InvokeRequired

To be

ListBox1.InvokeRequired

And

Me.Invoke(New MethodInvoker(AddressOf BackgroundProcess))

To be

ListBox1.Invoke(New MethodInvoker(AddressOf BackgroundProcess))

You're basically hosing the UI thread with a massive amount of updates so it never gets a chance to respond to the user input. Change the loop to sleep for a small amount of time.

    Do While True
        Me.ListBox1.Items.Add("Iteration:" & i)
        i += 1
        Thread.Sleep(100)
    Loop
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top