Threads in VB.NET 2005

FernandoL

New member
Joined
Nov 2, 2007
Messages
2
Programming Experience
Beginner
Hi,


I need to use threads in my application, but I want to make it thread-safe using VB.NET 2005


Here is a sample application just to illustrate my problem ( just a combobox and a button to start the thread ) :



VB.NET:
Public Class Form1

Public Thread1 As System.Threading.Thread

 
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

      Me.ComboBox1.Items.Add("line 1")

      Me.ComboBox1.Items.Add("line 2")

     Me.ComboBox1.Items.Add("line 3")

End Sub

 

Private Sub backgroundSub()

      MsgBox(Me.ComboBox1.SelectedIndex)

End Sub

 

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

     System.Threading.Thread.CurrentThread.Priority = System.Threading.ThreadPriority.Highest

     Thread1 = New System.Threading.Thread(AddressOf Me.backgroundSub)

     Thread1.Start()

End Sub

 

End Class
As you can see, I need to have access to controls values inside my thread

But I get this error :
Cross-thread operation not valid: Control 'ComboBox1' accessed from a thread other than the thread it was created on.



Exception details :



System.InvalidOperationException was unhandled
Message="Cross-thread operation not valid: Control 'ComboBox1' accessed from a thread other than the thread it was created on."
Source="System.Windows.Forms"
StackTrace:
at System.Windows.Forms.Control.get_Handle()
at System.Windows.Forms.Control.SendMessage(Int32 msg, Int32 wparam, Int32 lparam)
at System.Windows.Forms.ComboBox.get_SelectedIndex()
at WindowsApplication1.Form1.backSub() in F:\AAATESTES\testes\WindowsApplication1\WindowsApplication1\Form1.vb:line 13
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.runTryCode(Object userData)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()





The only way I can make it run is to alter the background sub this way :



VB.NET:
Private Sub backgroundSub()

     CheckForIllegalCrossThreadCalls = False

     MsgBox(Me.ComboBox1.SelectedIndex)

End Sub


But this is not thread-safe

thanks in advance
 
Last edited by a moderator:
Try the BackGroundWorker. Or read about Delegates (multithreading tutorials), they point to methods that can be invoked on UI thread. For example this is safe:
VB.NET:
'Dim Thread1 As New System.Threading.Thread(AddressOf threaded)
'Thread1.Start()

Sub threaded()
    ComboBox1.Invoke(New MethodInvoker(AddressOf safe))
End Sub

Sub safe()
    MsgBox(Me.ComboBox1.SelectedIndex)
End Sub
MethodInvoker is here a system defined delegate sub that takes no parameters.
 
thanks for the reply

I already use some Delegate subs to populate a ListView in the main thread

But How can I use a Delegate to retrieve a selectedItem value from a combobox inside a thread ?

Using the sample above, what I want is this :


Private Sub backgroundSub()

dim comboValue as integer = Me.ComboBox1.SelectedIndex

if comboValue = 1 then

' do this

else

' do that

end if


End Sub



How can I get in safe way control values ?
 
Last edited:
You didn't see the point of post 2 example? From a different thread you must use a delegate that is invoked on UI thread (me.invoke or thecontrol.invoke), this delegate must point to (addressof) the method that does the safe work.
 
Yeah like he said :D.

code example

'declaration on top
Delegate Sub SetTextCallback(ByVal valueAs String)


'just your function
Private Sub SetText(ByVal valueAs String)

If Form1.InvokeRequired Then
Dim d As New SetTextCallback(AddressOf SetText)
Form1.Invoke(d, New Object() {value})
Else
Form1.textBox.text = waarde
End If

End Sub

if you call SetText("I did it") in your thread it should work.

Greets
 
Back
Top