35

Possible Duplicate:
Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on

Okay, I know why this is giving me this error:

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

But... How can I make this workable?

System.Threading.Thread t = new System.Threading.Thread(()=>
{
   // do really hard work and then...
   listView1.Items.Add(lots of items);
   lots more UI work
});
t.Start();

I don't care when, or how the Thread finishes, so I don't really care about anything fancy or over complicated atm, unless it'll make things much easier when working with the UI in a new Thread.

2

2 Answers 2

27

You can't. UI operations must be performed on the owning thread. Period.

What you could do, is create all those items on a child thread, then call Control.Invoke and do your databinding there.

Or use a BackgroundWorker

    BackgroundWorker bw = new BackgroundWorker();
    bw.DoWork += (s, e) => { /* create items */ };
    bw.RunWorkerCompleted += (s, e) => { /* databind UI element*/ };

    bw.RunWorkerAsync();
Sign up to request clarification or add additional context in comments.

1 Comment

Solid answer, but I'm curious about why "You can't" is true. Do you have any further reading?
15

When you access the from's property from another thread, this exception is thrown. To work around this problem there's at least 2 options.

  1. Telling Control to don't throw these exceptions (which is not recommended):

    Control.CheckForIllegalCrossThreadCalls = false;

  2. Using threadsafe functions:

    private void ThreadSafeFunction(int intVal, bool boolVal)
    {
        if (this.InvokeRequired)
        {
            this.Invoke(
                new MethodInvoker(
                delegate() { ThreadSafeFunction(intVal, boolVal); }));
        }
        else
        {
            //use intval and boolval
        }
    }   
    

Comments