Click here to Skip to main content
15,894,825 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello everyone,

In the code below I'm learning threading.
The code runs fine but only thanks to the sub:

Private Sub Form1_Load (ByVal sender As System.Object, ByVal asSystem.EventArgs) Handles MyBase.Load
Me.CheckForIllegalCrossThreadCalls = False
End Sub

Without this sub I get error messages.
I understand that that is because I give the thread outside commands, namely: Label1.Text = Number1 or the like.

I know that I should now use invoke and delegate, but I do not know where exactly in this code because I don't understand invoke and delegate very well..

Maybe someone can help me further?

Thank you,

Eric



Public Class Form1

    Dim Number1 As Integer
    Dim Number2 As Integer
    Dim Thread1 As System.Threading.Thread
    Dim Thread2 As System.Threading.Thread

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.CheckForIllegalCrossThreadCalls = False
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Thread1 = New System.Threading.Thread(AddressOf Telop)
        Thread1.Start()
    End Sub

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        Thread2 = New System.Threading.Thread(AddressOf Telaf)
        Thread2.Start()
    End Sub

    Private Sub Telop()
        Do Until Number1 = 10000
            Number1 = Number1 + 1
            Label1.Text = Number1
            'Me.Refresh()
        Loop
    End Sub 'Telop

    Private Sub Telaf()
        Number2 = 10000
        Do Until Number2 = 0
            Number2 = Number2 - 1
            Label2.Text = Number2
            'Me.Refresh()
        Loop
    End Sub 'Telaf

End Class


What I have tried:

vb2017: What and why invoke and delegate?
Posted
Updated 23-Dec-18 2:20am

Delegates are what other languages loosely refer to as "function pointers".

Since you can't touch a control from another thread, you have to use a Sub or Function to update the control how you want. Now, you have to call this method somehow, but you have to do it in a way that says "I want this thread to call that method." This is where the Invoke comes in.

In your example, you could have a Sub that sets the Text property of a specific label control:
VB.NET
Private Delegate Sub UpdateLabel1Delegate(ByVal message As String)

Private Sub UpdateLabel1Text(ByVal message As String)
    If Label1.InvokeRequired Then
        ' This is a cross-thread call, so
        ' invoke a call back to this method.
        Me.BeginInvoke(New UpdateLabel1Delegate(AddressOf UpdateLabel1Text), message)
    Else
        ' We're being called on the UI thread, so just update the label.
        Label1.Text = message
    End If
End Sub

.
.
.

   ' Code running on a non-UI thread...
   UpdateLabel1Text("This is a test...")
 
Share this answer
 
Cross thread calls are when you start a new thread and it tries to access any UI element - because they are "owned" by the original thread - the UI thread - and things start to go rather pear shaped if the same control is accessed from multiple threads, in exactly the same way that you have one driver in a car: more people trying to steer at the same time would not help!

Setting CheckForIllegalCrossThreadCalls to False means that the system doesn't raise an exception when you do try from the wrong thread. That's not a good thing: it doesn't fix potential problems it just makes your code not know about them - a bit like the driver not being told that his mate in the back seat also has a steering wheel. The car still doesn't work properly, but now the driver doesn't know why because he hasn't been told. Worse, until your app crashes as a result, you won't necessarily know that your data is corrupt and that can cause some real problems (imagine if your bank didn't know it took money from your account instead of mine).

Invoke seems complicated, but it isn't, not really. All you have to do is check what thread you are using the Control.InvokeRequired Property [^] and if it is set, you use Invoke to run a method on the original thread: How to: Manipulate Controls from Threads[^]
 
Share this answer
 
At first I suggest that you read something more about those things ...

Then - to your question :
You have declared your 2 Threads.
With the Button-Click you delegate a Method to one of this Threads. Now it will be executed.
Inside your Thread-Method you try to access an element from the Main-Thread (Label2). This is not possible because an element only can belong to one owner - in this case the Main-Thread.
So you have to build an Invoke-Method which enables the Control to do it's job when it's able to do it.

But when you change your code that it works right (invoking) you would not see an increasing value inside the Label because your Thread executes it's job in Milliseconds. You should enter a Thread.Sleep inside your method ...
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900