CraigWardman.com

[ Thread.Join Deadlock with Invoke ]

/Blog/Post

Thread.Join Deadlock with Invoke

If you are trying to Make Thread-Safe Calls to Windows Forms Controls then you can run into deadlock problems when calling ‘Invoke’ from your thread, if your main thread is waiting for a Thread.Join on the calling thread.

I posted a workaround for this on the Microsoft site, which uses an extra thread to make the call to Invoke method, to avoid the deadlock.

VB.NET example:

Private Sub SetText(ByVal str_text As String)
        If Me.textbox1.InvokeRequired = True Then
                'call an asyncronous invoke, by calling it then forcing a DoEvents
                Dim asyncInvokeThread As New Threading.Thread(New Threading.ParameterizedThreadStart(AddressOf AsyncInvoke))
                asyncInvokeThread.IsBackground = True
                asyncInvokeThread.Start(str_text)
 
                Application.DoEvents()
        Else
                me.textbox1.text=str_text
        End If
End Sub
Private Sub AsyncInvoke(ByVal obj_text As Object)
        Dim str_text As String = CStr(obj_text)
        Dim d As New SetTextCallback(AddressOf SetText)
        Me.Invoke(d, New Object() {str_message})
End Sub

Share This!

2 Comments to Thread.Join Deadlock with Invoke

  1. Bart's Gravatar Bart
    January 6, 2011 at 8:13 am | Permalink

    Hi,

    I know this is an old article (http://www.craigwardman.com/blog/index.php/2007/09/thread-join-deadlock-with-invoke/)

    However I am in a situation that looks very similar. I have an PDA application with weird hangups that I can’t trace back to any part of the code. I do use invokerequired.

    I just ported the PDA application (.NETCF) to .NET and found this morning I have a similar looking hangup. With Spy++ I found that I am in a race condition with WM_PAINT messages, and acutally I only use invokerequired with the refresh method on the UI thread.

    As sample (a timer callback in the UI)

    Private Sub onChangingTimerTimeout(ByVal state As Object)
    changingSystem = False
    Try
    If Me.InvokeRequired Then
    Me.Invoke(refreshDelegate)
    Else
    Me.Refresh()
    End If
    Catch ex As Exception
    End Try
    End Sub

    the refreshDelegate is a simple method calling me.refresh().

    I would appreciate very much if you could let me know if the code as I wrote here is exposing me to this deadlock situation.

    Kind regards

    Bart

Leave a Reply

*
CraigWardman.com
Car Leasing | Lease Cars