Posts Tagged ‘threading’
Multi-threading, delegates & invoke in windows forms
Multi-threading was not the intended approach to my program, by suddenly after making some changes I received messages that I was on the wrong thread. I had ‘Imports System.Threading’ in only one module, and all it did was thread.wait(200). That was just to give excel time to recalculate after setting a value before reading it back to check the format.
Perhaps it was the addition of the second timer control. It was certainly occurring on that thread.
So after much experimentation I ended up with a simplified example from http://msdn.microsoft.com/en-us/library/a1hetckb.aspx
Two things to note:
After the execution of :
”myDelegate = New AddListItem(AddressOf AddListItemMethod)”
myDelegate must have both a method and a target. It does not seem to be able to do this unless it is executed from within the form class.
The command “Me.Invoke(Me.myDelegate, New Object() {myString})” in GenerateStrng must also be within the form Class, even if the addressing is changed to MyFormControl
Here is the code, with some helpful Debug.Prints to help you see whats really happening. (apologies about the colour!)
Imports System
Imports System.Drawing
Imports System.Windows.Forms
Imports System.Threading
Public Class MyFormControl
Inherits Form
Delegate Sub AddListItem(ByVal myString As String)
Public myDelegate As AddListItem
Private myButton As Button
Public myThread As Thread
Private myListBox As ListBox
Public Sub New()
myButton = New Button()
myListBox = New ListBox()
myButton.Location = New Point(72, 160)
myButton.Size = New Size(152, 32)
myButton.TabIndex = 1
myButton.Text = “Add items in list box”
AddHandler myButton.Click, AddressOf Button_Click
myListBox.Location = New Point(48, 32)
myListBox.Name = “myListBox”
myListBox.Size = New Size(200, 95)
myListBox.TabIndex = 2
ClientSize = New Size(292, 273)
Controls.AddRange(New Control() {myListBox, myButton})
Text = ” ‘Control_Invoke’ example “
myDelegate = New AddListItem(AddressOf AddListItemMethod)
Dim tid As Integer = Thread.CurrentThread.ManagedThreadId
Debug.Print(“New tid:” & tid.ToString)
AddListItemMethod(“New ” & tid.tostring)
End Sub ‘New
Shared Sub Main()
Dim myForm As New MyFormControl()
myForm.ShowDialog()
End Sub ‘Main
Public Sub AddListItemMethod(ByVal myString As String)
Dim tid As Integer = Thread.CurrentThread.ManagedThreadId
Debug.Print(“AddListItemMethod tid:” & tid.ToString)
myListBox.Items.Add(myString)
End Sub ‘AddListItemMethod
Private Sub Button_Click(ByVal sender As Object, ByVal e As EventArgs)
myThread = New Thread(New ThreadStart(AddressOf GenerateStrng))
myThread.Start()
End Sub ‘Button_Click
Public Sub GenerateStrng()
Dim i As Integer
Dim tid As Integer = Thread.CurrentThread.ManagedThreadId
Debug.Print(“ThreadClass.Run tid:” & tid.ToString)
For i = 1 To 5
Dim myString As String = “Step ” + i.ToString() + ” executed from ” & tid.ToString
‘ Execute the specified delegate on the thread that owns
‘ ‘myFormControl1′ control’s underlying window handle with
‘ the specified list of arguments.
Me.Invoke(Me.myDelegate, New Object() {myString})
Thread.Sleep(800)
Next i
End Sub ‘Run
Private Sub MyFormControl_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
End Sub
Private Sub InitializeComponent()
Me.SuspendLayout()
‘
‘MyFormControl
‘
Me.ClientSize = New System.Drawing.Size(292, 266)
Me.Name = “MyFormControl”
Me.ResumeLayout(False)
End Sub
End Class ‘MyThreadClass