I'm quite new at vb.net and using different threads so I don't exactly know how to use the invoke method. I basically want to assign selected_item as the one that user has selected in combobox from UI thread.
Dim selected_item As String
If ComboBox1.InvokeRequired Then
selected_item = ComboBox1.Invoke(ComboBox1.SelectedItem)
Else
selected_item = ComboBox1.SelectedItem
End If
I get the error cross-thread operation not valid. How can I fix this?
CodePudding user response:
When you call Invoke
you need to specify a method that gets invoked on the UI thread. If you want to get a value, that method has to return that value and then Invoke
will return that same value on your secondary thread. In your case:
Private Function GetComboBox1SelectedItem() As Object
If ComboBox1.InvokeRequired Then
Return ComboBox1.Invoke(New Func(Of Object)(AddressOf GetComboBox1SelectedItem))
Else
Return ComboBox1.SelectedItem
End If
End Function
You can then call that GetComboBox1SelectedItem
method on any thread and it will return you the currently selected item.
If you call that method on a secondary thread, InvokeRequired
is True
and execution enters the If
block. In that block, the Invoke
method creates a delegate, marshals it to the UI thread and invokes it. That delegate is for the same method, so it gets executed a second time. The second time, we're on the UI thread so InvokeRequired
is False
and execution enters the Else
block. In that block, the Selecteditem
is retrieved and returned. The Invoke
method then returns the value returned by that second instance of the method and that gets returned by the first instance.
You might like to read this for a more rigorous explanation of how to build such methods and what they actually do.
CodePudding user response:
Little bit shorter
Dim selected_item As String
If ComboBox1.InvokeRequired Then
selected_item = ComboBox1.Invoke(Sub() ComboBox1.SelectedItem)
Else
selected_item = ComboBox1.SelectedItem
End If