Tamilmaran
Tamilmaran

Reputation: 1347

What exactly is happening with windows form threads?

In an asynchronous OnMsgRecieved call, if I assign a value directly to a control it is not working. Then i came to know that it was due to thread unsafe and i got following code to resolve the issue. Now it is working. But i am not sure what it does practically. Can any one make me to understand it fully? The code is:-

        public void listener_OnMsgRecieved(string aResponse)
    {
        ShowResponseMessage(aResponse);
    }

    public void ShowResponseMessage(string aResponse)
    {
        // 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 (this.listBox.InvokeRequired)
        {
            SetTextCallback d = new SetTextCallback(ShowResponseMessage);
            this.Invoke(d, new object[] { aResponse });
        }
        else
        {
            this.listBox.Items.Add(aResponse);
            label.Text = "Response received from Server :";
        }
    }

Upvotes: 2

Views: 205

Answers (2)

Chris Taylor
Chris Taylor

Reputation: 53699

When ShowResponseMessage is called on a different thread from that of the UI, the InvokeRequired will return true, then you are using Control.Invoke to send a message to the Windows message queue.

The UI message pump which runs in the UI thread will pull the message and deliver it to the target control, the target control then sees that this is a message requesting that a delegate be invoked and the delegate is invoke by the control, this is now running on the UI thread and therefore the cross threading issue has been resolved.

The trick is that the delegate is not called directly on the non-UI calling thread. Using Windows messages the instruction to execute the delegate is passed to the UI thread which then executes the delegate in response to the message. 'Control.Invoke' uses the Windows [SendMessage][1], Control.BeginInvoke uses the [PostMessage][2] Win32 API to facilitate the message passing.

Upvotes: 1

Adriaan Stander
Adriaan Stander

Reputation: 166396

UI Controls cannot be update/changed from any thread other than the main thread/thread it was created on.

In your case the check InvokeRequired does the check to see if the thread that wishes to change the control is the creating thread, and if not passes the call back to the main thread/creator.

Have a look at How to: Make Thread-Safe Calls to Windows Forms Controls

If you use multithreading to improve the performance of your Windows Forms applications, you must make sure that you make calls to your controls in a thread-safe way.

Access to Windows Forms controls is not inherently thread safe. If you have two or more threads manipulating the state of a control, it is possible to force the control into an inconsistent state. Other thread-related bugs are possible, such as race conditions and deadlocks. It is important to make sure that access to your controls is performed in a thread-safe way.

It is unsafe to call a control from a thread other than the one that created the control without using the Invoke method.

Upvotes: 0

Related Questions