34

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.

Community
  • 1
  • 1
  • +1 @blue, yeah there seems to be a whole class of similar questions regarding this all asked in a slightly different way but with the same core idea that UI operations must be performed on the same thread. – Joe Feb 18 '11 at 04:17
  • 1
    This has been asked many times before. Check this out: http://stackoverflow.com/questions/1523878/cross-thread-operation-not-valid-in-c or http://stackoverflow.com/questions/1485786/error-cross-thread-operation-not-valid or http://stackoverflow.com/questions/1377529/cross-thread-operation-not-valid or http://stackoverflow.com/questions/1397370/cross-thread-operation-not-valid-in-c or http://stackoverflow.com/questions/4010602/c-cross-thread-operation-not-valid or http://stackoverflow.com/questions/3439065/cross-thread-operation-not-valid-in-c – Joe Feb 18 '11 at 04:05

2 Answers2

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();
Adam Rackis
  • 82,527
  • 56
  • 270
  • 393
  • Solid answer, but I'm curious about why "You can't" is true. Do you have any further reading? – Matt Jul 26 '16 at 03:41
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
        }
    }   
    
Alireza Noori
  • 14,961
  • 30
  • 95
  • 179