Tuesday, February 12, 2008

Illegal Cross Thread Operation?

Submit this story to DotNetKicks

I see many forumposts solving this problem by simply adding the CheckForIllegalCrossThreadOperations=false;

While this is a totally legit workaround, it is highly thread-unsafe, and should only be used for debugging purposes. To be able to update for instance form-components from another thread, you will need to use delegates and invoke. Sounds scary? Not really.

A delegate is simply a "blueprint" that describes how a particular function or method should look. In C++ world, delegates are similar to Function pointers, but since we don't work with pointers in C# this is the closest we get. Still, function pointer is not a correct definition, as the delegate won't point to a function unless you make it do so. Here's an example:

The function


private void UpdateStatusText(string statusText)
{
statusLabel.Text = statusText;
}


Would have the following delegate:


public delegate void UpdateStatusTextHandler(string statusText);


Both the delegate name and the parameter-name(s) are totally random, it is the return-type and parameter-types that are important.

Let's say we have an eventhandler thread_OnStatusChanged(string newStatus) that needs to update the statusLabel.Text property. If the thread is different from the one the statusLabel exists in, you will get the Illegal Cross Thread operation error if you simply try to update it.

What we first want to do is an if-check to see if it comes from a different thread.
Inside the thread_OnStatusChanged eventhandler we do the following:



if (statusLabel.InvokeRequired)
{
statusLabel.Invoke(new UpdateStatusTextHandler(UpdateStatusText), newStatus);
}



The Invoke function takes the arguments Delegate Method, as well as the optional args[] to enable you to pass the required arguments to your method.

So by doing the new UpdateStatusTextHandler(UpdateStatusText) you are simply creating a pointer to the method UpdateStatusText(string statusText)



Hopefully this will make delegates and invoking a little more understandable.

Good luck with your threads!

2 comments:

Anonymous said...

Great article! I've been looking for a solution to this, and finally I got it1

Yngve B. Nilsen said...

Thanks! Glad you liked it :)