Make Thread-Safe Calls to Windows Forms Controls

I have an application that uses remoting - the usual pattern - Client calls a proxy of a remote object - remote object fires events which are broadcast to the client using delegates and call back - client recieves the broadcast messages and it has to display it on a form.

The problem occurs in the last part. I use the thread safe method of calling the form rich text control.

Private Sub ClientEventHandler(ByVal Msg As String) Handles RemoteEvent

'I confirmed that Msg has the write value

SetText(Msg)

End Sub

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.RichTextBox1.InvokeRequired Then

Dim d As New SetTextCallback(AddressOf SetText)

Me.Invoke(d, New Object() {[Text]})

Else

Me.RichTextBox1.AppendText([Text])

End If

End Sub

Everything works fine until the execution of Me.Invoke(d, New Object() {[Text]}). The form hangs(the execution of this one statement takes forever) at this point.

Please let me know what the reason could be.



Answer this question

Make Thread-Safe Calls to Windows Forms Controls

  • computerbill

    BTW, because the control on a form *must* be created on the same thread as it's parent Form.InvokeRequired can be used to test if [Begin]Invoke is required for all child controls...

  • Alibong

    Are you sure that

    Me.RichTextBox1.AppendText([Text])

    is not trying to be called instead


  • Bryce Beagley

    Can you tell me how to simulate the same pattern in a class (non windows form)

    To be more specific can you give me or point me to a place where I can get some code snippets - specifically the contents of the InvokeRequired method of the windows controls.

    Thanks.


  • SpoonsJTD

    The main GUI thread, the one that create the form and its controls, must be idle and pumping messages. If it isn't, for example if it is blocked waiting for the remoting thread to finish executing, you might have created a deadlock.


  • ks06

    You're not using InvokeRequired/Invoke on the same object. You're testing the RichTextBox1's InvokeRequired then calling Invoke on the Form. Try "If Me.InvokeRequired..." then change "Me.Invoke" to "Me.BeginInvoke". Because Form.Invoke is a blocking call and you're performing cross-thread invocation you have the very real possibility that something in the GUI thread is synchronized on something that the thread that calls Invoke has locked, ergo a deadlock. Unless you really need to invoke something on the GUI thread synchronously, use BeginInvoke instead.

  • ozhonetech

    Peter,

    Many thanks for your reply. Your suggestions worked.

    Actually I was not very familiar with the multithreading and GUI. I just took the thread safe method right from MSDN.


  • Make Thread-Safe Calls to Windows Forms Controls