Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 832
fotg Avatar asked Jan 18 '26 10:01

fotg


2 Answers

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

     Control.CheckForIllegalCrossThreadCalls = False
like image 192
Malik Usman Avatar answered Jan 21 '26 01:01

Malik Usman


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.

like image 35
Rohit Vats Avatar answered Jan 20 '26 23:01

Rohit Vats



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!