fotg
fotg

Reputation: 639

Cross-thread operation not valid, control accessed from thread other than the thread it was created on

I am getting an error "Cross-thread operation not valid: Control 'AllOtherStatus' accessed from a thread other than the thread it was created on."

I have this code: _output is set to AllOtherStatus, looking at the debugger, _output.InvokeRequired is false

This code was working fine until I changed an unrelated class which doesn't use this piece of code. Code gets to the else statement then throws the exception.

private void Thread(Object p)
        {
        lock (this)
            {
            if (_output.InvokeRequired)
                {
                if(s!= null)
                    _output.Invoke(new MethodInvoker(delegate { _output.AppendText(s); }));
                }
            else
                _output.AppendText(s);

            s = null;
            }
        }

So my question is why is _output.InvokeRequired suddenly returning false when it should clearly be returning true?

Upvotes: 3

Views: 6824

Answers (2)

Malik Usman
Malik Usman

Reputation: 61

use this on form load or some where else before thread execution

     Control.CheckForIllegalCrossThreadCalls = False

Upvotes: 6

Rohit Vats
Rohit Vats

Reputation: 81233

From MSDN documentation -

InvokeRequired can return false if Invoke is not required (the call occurs on the same thread), or if the control was created on a different thread but the control's handle has not yet been created.

In the case where the control's handle has not yet been created, you should not simply call properties, methods, or events on the control. This might cause the control's handle to be created on the background thread, isolating the control on a thread without a message pump and making the application unstable.

You can protect against this case by also checking the value of IsHandleCreated when InvokeRequired returns false on a background thread. If the control handle has not yet been created, you must wait until it has been created before calling Invoke or BeginInvoke. Typically, this happens only if a background thread is created in the constructor of the primary form for the application (as in Application.Run(new MainForm()), before the form has been shown or Application.Run has been called.

It might be possible that unrelated code change defer the creation of handle for control. Can you check by explicitly creating handle before checking invoke required -

var handle = this.Handle;
if (_output.InvokeRequired)
{
  .....
}

Refer to the answers here. They might be of your interest.

Upvotes: 2

Related Questions