Question

If I am setting the Text property of a Form from a non-UI thread, then I need to use Invoke to avoid a cross-thread error. But, I can read the Text property without using Invoke. Is this safe? If I try to read the Handle property of a Form I get a cross-threading error. If I read the IsDisposed property of a Form it works fine. How can I tell when I need to use Invoke? Should I always be using Invoke to read and write property values?

Was it helpful?

Solution

Whenever you are in a thread other from the UI thread you should use Invoke when accessing UI objects. Use InvokeRequired property to find out if you are in fact, in a different thread.

OTHER TIPS

The easiest way is to use:

Delegate Sub SetTextCallback(ByVal [text] As String)

Private Sub SetText(ByVal [text] As String)
' InvokeRequired required compares the thread ID of the
' calling thread to the thread ID of the creating thread.
' If these threads are different, it returns true.
If Me.lboxResults.InvokeRequired Then
    Dim d As New SetTextCallback(AddressOf SetText)
    Me.Invoke(d, New Object() {[text]})
Else
    Me.lboxResults.Items.Add([text])
End If

End Sub

Sorry for the VB Code...

Another option is to use SynchronizationContext. This would work not only for WinForms, but also for WPF and ASP.NET, and it is available since .NET 2.0.

Call SynchronizationContext.Current on the main thread (e.g. in the constructor), and use the returned object whenever you need to synchronize calls. If the object is null, you don't need synchronization.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top