Paul Liebrand's Weblog

Welcome to my blog mainly about SharePoint

Skip to: Content | Sidebar | Footer

Simple Pattern / Solution for Cross-thread operation not valid

16 July, 2010 (10:54) | .NET | By: Paul Liebrand

If you have ever done any threaded programming in .NET WinForms you have more than likely run into the following error message at some point:

Cross-thread operation not valid 

InvalidOperationException was unhandled

Cross-thread operation not valid: Control ‘’ accessed from a thread other than the thread it was created on.

This exception is normally displayed while running in DEBUG mode. In release mode, everything appears to run as expected but at some point you will definitely run into a thread deadlock issue.

The following code represents a pattern I would use to get around this problem and I insured all the calls that would touch the UI from a different thread followed it:

 
private void button2_Click(object sender, EventArgs e)
{

    ThreadPool.QueueUserWorkItem(notUsed =>
    {
        for (int i = 0; i < 100; i++)
        {
            UpdateStatus(string.Format("Loading record {0} of 100", i, 100));
        }
    });
}

private void UpdateStatus(string message)
{
    if (InvokeRequired)
    {

        BeginInvoke((MethodInvoker)delegate() { UpdateStatus(message); });
        return;
    }

    textBox1.Text = message;
}

Although this pattern works it is not as elegant and can be further refined and simplified. To accomplish this I created an extension method for the Form as such:

    public static class FormExtensions
    {
        public static void HandleCrossThreadUI(this Form form, MethodInvoker code)
        {
            if (form.InvokeRequired)
            {
                form.BeginInvoke(code);
                return;
            }

            code.Invoke();
        }
    }

By modifying the original code above to make use of the extension I can simply the code a little further:

private void button2_Click(object sender, EventArgs e)
{

    ThreadPool.QueueUserWorkItem(notUsed =>
    {
        for (int i = 0; i < 100; i++)
        {
            UpdateStatus(string.Format("Loading record {0} of 100", i, 100));
        }
    });
}

private void UpdateStatus(string message)
{
    this.HandleCrossThreadUI(() => { textBox1.Text = message; });
}

This may not look like much but when you start adding more and more code, it becomes a lot easier to read.

Hopefully you find this a little useful.

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Reddit

Comments

Pingback from Tweets that mention Paul Liebrand’s Weblog » Simple Pattern / Solution for Cross-thread operation not valid — Topsy.com
Time July 16, 2010 at 11:29 am

[...] This post was mentioned on Twitter by Planet SharePoint and Paul Liebrand, Erik Neumann. Erik Neumann said: #sharepoint Simple Pattern / Solution for Cross-thread operation not valid: If you have ever done any threaded pro… http://bit.ly/afIPIE [...]

Write a comment





blog comments powered by Disqus