<< Chapter < Page | Chapter >> Page > |
The problem occurs because the thread Task1 is running separate from the Form thread so the Form thread and the Task1 thread could change the TextBox object at the same time.
To fix this problem you can use a Delegate that points to a function that runs in the Form thread. Suppose the code was changed to the following:
' This defines a delegate subroutine that takes an integer as its input
Delegate Sub InvokeDelegate(ByVal myStr As String)' This makes an instance of the delegate that points to the address
' of the InvokeMethod function. When the delegate is invoked it will' run the InvokeMethod method on the thread that owns the window handle.
Dim IDel As New InvokeDelegate(AddressOf InvokeMethod)Private Sub Task1()' The Invoke method executes the specified
' delegate on the thread that owns the control's' underlying window handle
TextBox1.Invoke(IDel, "Task Text")End SubPublic Sub InvokeMethod(ByVal myStr As String)
TextBox1.Text = myStrEnd Sub
This code section does not contain the whole program since it doesn't show starting the Task1 thread, etc. Lets look at the code one line at a time.
Delegate Sub InvokeDelegate(ByVal myStr As String)
This line defines a delegate that will have one parameter on its input and that parameter will be passed by value and is a string. The delegate type is called
InvokeDelegate
. The name of the delegate type can be anything.
Dim IDel As New InvokeDelegate(AddressOf InvokeMethod)
This line creates an instance of the delegate type defined above (
InvokeDelegate
). The method or function it uses for the instance is the static method
InvokeMethod
which is defined later in the code. This means that
IDel
is an instance of a delegate and the instance is a static method defined by
InvokeMethod
. When
IDel
is used it will execute an
InvokeMethod
method.
TextBox1.Invoke(IDel, "Task Text")
Control objects have a method called
Invoke
. This method will execute a delegate on the thread that created the object. So, we first create a delegate
IDel
and then when the
Invoke method
is called for the TextBox1 object, the
IDel
delegate gets executed on the thread that created the TextBox1 control. This thread happens to be the Form thread. The
Invoke
method will not continue until the delegate completes.
If you don't want the calling thread to wait for the delegate to finish you can use the control method
BeginInvoke
.
Public Sub InvokeMethod(ByVal myStr As String)
TextBox1.Text = myStrEnd Sub
This is the method that is used for the delegate. Notice that it has the same input as defined above (a string input passed by value). The method simply takes the input string and assigns it to the
TextBox1.Text
property.
In this simple example there will be a Form that contains a TextBox. Also, a thread will be started that periodically writes to the TextBox. The TexBox is created by the Form thread and while the Form is running you can enter text into the TextBox. However, periodically the other thread will write to the TextBox and clear anything that has been typed into it.
Since the thread is seperate from the Form thread, there needs to be a delegate that the thread uses to write to the TextBox.
Imports System.ThreadingPublic Class Form1
' This defines the thread that will run method ThreadMethodDim thread As New Thread(AddressOf ThreadMethod)
' This defines a delegate type that takes an integer as its input.' The delegate type is named DelegateType.
Delegate Sub DelegateType(ByVal myStr As String)' This makes an instance of the delegate type that points to the address
' of the DelegateMethod method. When the delegate is invoked it will' run the InvokeMethod method on the thread that owns the window handle.
Dim IDel As New DelegateType(AddressOf DelegateMethod)Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load' When the form loads the other thread will be set up and started
' Make this thread a background thread so it automatically' aborts when the main program stops.
thread.IsBackground = True' Set the thread priority to lowest
thread.Priority = ThreadPriority.Lowest' Start the thread
thread.Start()End Sub' This method is the thread that runs separate from the Form1 thread.
' It continues to run and every 5 seconds it invokes the delegate that' runs in the Form1 thread.
Private Sub ThreadMethod()' The Invoke method executes the specified
' delegate on the thread that owns the control's' underlying window handle
While 1Thread.Sleep(5000)
TextBox1.Invoke(IDel, "Task Text")End While
End Sub' This method runs in the Form1 threadPublic Sub DelegateMethod(ByVal myStr As String)
TextBox1.Text = myStrEnd Sub
End Class
Notification Switch
Would you like to follow the 'Ti dsp/bios lab' conversation and receive update notifications?