cjard
Well-known member
- Joined
- Apr 25, 2006
- Messages
- 7,081
- Programming Experience
- 10+
Hi All
Quick question as I'm implementing a thread safe way of reading the value from a control
In an app, I have the need to have a background worker enumerate an array of controls and read their values. To solve it I did this (
I find that the app hangs, and a look at the thread window seems to indicate that one thread is stopped at Invoke, and the other is stopped on the Join..
As you can probably guess, I was coding to avoid the situation whereby the worker thread goes and grabs the value before the gui thread has moved it..
Given that the app blocks, i think the UI thread is waiting for the worker thread, which is blocked on the call to Invoke..
Hence my question: Does Invoke() block until the GUI thread has finished? If it does, then I can ignore the need to make the worker thread sleep.. If it does not, then a) why does the app hang, and b) how to ensure that the worker thread doesnt attempt to retrieve the value before the gui thread has finished copying it?
Quick question as I'm implementing a thread safe way of reading the value from a control
In an app, I have the need to have a background worker enumerate an array of controls and read their values. To solve it I did this (
VB.NET:
Class SingleChoiceArgument
Inherits Arguments.GenericArgument
Private cb As ComboBox
Private toRet As Object = ""
Private waitingThread As System.Threading.Thread
Private Delegate Sub TransferValueCallback()
Public Sub New(ByVal dispValMembers As RealDS.DispValDataTable)
[COLOR=seagreen]'snip[/COLOR]
End Sub
Public Overloads Overrides Function GetValue() As Object
[COLOR=seagreen][I]'if current thread did not create the combobox[/I][/COLOR]
If cb.InvokeRequired Then
[COLOR=seagreen][I]'new delegate[/I][/COLOR]
Dim tvcb As TransferValueCallback = AddressOf transferValueSafely
[COLOR=seagreen][I]'store the current thread reference so we can wake it up later[/I][/COLOR]
[COLOR=seagreen][I] [COLOR=black]waitingThread = System.Threading.Thread.CurrentThread[/COLOR] [/I][/COLOR]
[COLOR=seagreen][I] 'bein an invoke, which will make the combo's thread copy the value for us[/I][/COLOR]
[COLOR=seagreen][I] 'it will then attempt to join the waiting thread.. i.e. it will wait for the waiting[/I][/COLOR]
[COLOR=seagreen][I] 'thread, or it will wake it from its sleep[/I][/COLOR]
cb.Invoke(tvcb)
[COLOR=seagreen][I]'put the current thread to sleep[/I][/COLOR]
System.Threading.Thread.Sleep(10000)
Else
toRet = cb.SelectedValue
End If
Return toRet
End Function
Private Sub transferValueSafely()
[COLOR=seagreen][I] 'the GUI thread will move the value for us..[/I][/COLOR]
toRet = cb.SelectedValue
[COLOR=seagreen][I]'it will then wake up the sleeping worker thread[/I][/COLOR]
waitingThread.Join
End Sub
End Class
I find that the app hangs, and a look at the thread window seems to indicate that one thread is stopped at Invoke, and the other is stopped on the Join..
As you can probably guess, I was coding to avoid the situation whereby the worker thread goes and grabs the value before the gui thread has moved it..
Given that the app blocks, i think the UI thread is waiting for the worker thread, which is blocked on the call to Invoke..
Hence my question: Does Invoke() block until the GUI thread has finished? If it does, then I can ignore the need to make the worker thread sleep.. If it does not, then a) why does the app hang, and b) how to ensure that the worker thread doesnt attempt to retrieve the value before the gui thread has finished copying it?