Question Multithreading Example

Lepi

New member
Joined
May 1, 2013
Messages
3
Programming Experience
Beginner
Hello this is my first post on this Forum. I'm coming from MrExcel Forums as i started on VBA with access, i know im a noob. I have transferred to VB and SQL server but im trying to pick up a new concept to me, threading. I have looked around and found some examples but i haven't found anything that helps me understand how to use the same sub of function between multiple threads at the same time.

Can someone help me change this to work so understand how multithreading handles usage of the same function at the same time?

VB.NET:
Option Explicit On
Imports System.Threading
Imports System.ComponentModel

Public Class Form1

 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim thread1 As New Thread(New ThreadStart(Sub() countup(Me.Label1)))
        thread1.Start()
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim thread2 As New Thread(New ThreadStart(Sub() countup(Me.Label2)))
        thread2.Start()
    End Sub

    Private Delegate Sub CountDelegate(ByVal Label As Object)

    Private Function countup(ByVal Label As Object)
        countup = False
        If (InvokeRequired) Then
            Invoke(New CountDelegate(AddressOf countup), Label)
        Else
            For i = 0 To 10000
                Label.Text = i.ToString
                'Thread.Sleep(100)
            Next
        End If
        countup = True
    End Function
End Class
 
Your use of multiple threads is pointless. You start a new thread and execute 'countup' as the entry point but the very first thing 'countup' does is invoke a second instance of the same method back on the UI thread. The point of multi-threading is to allow multiple things to happen at once. You want to perform one or more tasks in the background while the UI remains responsive to user input and OS messages. You need to actually do some work on the background thread and then only invoke back to the UI thread intermittently to update the UI.
Imports System.Threading

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim thread1 As New Thread(New ThreadStart(Sub() CountUp(Me.Label1)))
        thread1.Start()
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim thread2 As New Thread(New ThreadStart(Sub() CountUp(Me.Label2)))
        thread2.Start()
    End Sub

    Private Sub CountUp(ByVal label As Control)
        For i = 1 To 10000
            'Do some work on the background thread.
            Thread.Sleep(100)

            'Update the UI.
            SetControlText(label, i.ToString())
        Next
    End Sub

    Private Sub SetControlText(target As Control, text As String)
        If target.InvokeRequired Then
            target.Invoke(New Action(Of Control, String)(AddressOf SetControlText), target, text)
        Else
            target.Text = text
        End If
    End Sub

End Class
 
That is not really a good example of threading, as everything you posted affects the UI, so everything will necessarily be executed on the UI thread. Your code however is close to what it would be otherwise.

Think of the UI thread as Santa Claus, and the other threads are Santa's little helpers. Santa can't greet the kids and fly his shiny sled if he also has to make the toys and feed the reindeers. And you cannot ever have a little helper greet the kids, let alone pilot the sled. You can have two or more little helpers on the same project (two threads executing same procedure) if you like, but there is only room for 3 little helpers working at once in the quad core workshop.

So, dubious analogies aside, the rest of your code shows you should understand how it works just fine.
 
Ok i see i did the invoke at the wrong point and it should only be when im manipulating anything in the UI? All the example i saw duplicated the CountUp and SetControlText for some reason, witch confused me. Thank you this does help. Also i noticed you did not declare a delegate, why? Does action work best in the scenario? I should probably state what i will be applying all of this too. I have an ETL going on which takes awhile and i wanted to run multiples while sending information back to a progress bar so i know hows its doing. Also is this the best way to do this or should i be using threadpool or background worker?
 
Lot's of multi-threading examples use Thread.Sleep and a loop because it's an easy and generic way to represent an operation that takes some time to perform on a thread and updates the UI intermittently. Any particular background operation may involve a loop but it may not, or it might involve several loops in various combinations. Just like any other code you write, a background task can take any form at all. The only requirement is that it doesn't update the UI directly. The Thread.Sleep calls can be replaced with any code that does work.

It's generally preferable not to create Thread objects directly or even use the ThreadPool directly. In a GUI app, if you have a small, specific number of background tasks to complete then the BackgroundWorker is a good option. It provides a simple mechanism to update the UI and to pass data between threads. Under the hood, it uses the ThreadPool. Beyond that, it is preferred to use the Task Parallel Library, which was introduced in .NET 4.0 and extended in .NET 4.5. The Task class encapsulates a background task and is the heart the new .NET parallelism.

If you want to invoke a method with no parameters and no return value then it is preferred to use the MethodInvoker delegate, which is more efficient than any other delegate besides EventHandler. Prior to .NET 3.5, for methods with other signatures you needed to declare your own delegates. The Action and Func delegates were added in .NET 3.5 to support LINQ and it is easier just to use them in most cases. I would only declare a delegate of my own if it was being exposed as part of a public API. If it's just used within the one project then I'd definitely use Action or Func, which can each support up to 16 parameters as of .NET 4.0, although only up to 4 parameters in .NET 3.5.
 
There is no way to debug into a thread is there?
All code is executed on a thread so of course. If you put a breakpoint on a line of code then execution will break at that line, no matter what thread it's executed on. The problem is, while one thread is halted, any other threads are continuing to execute. That's one of the reasons that debugging multi-threaded code is quite difficult.
 
Back
Top