If you look at the Reference Source for Control.InvokeRequired:
Reference Source[
^] it shows you the code:
public bool InvokeRequired {
get {
using (new MultithreadSafeCallScope())
{
HandleRef hwnd;
if (IsHandleCreated) {
hwnd = new HandleRef(this, Handle);
}
else {
Control marshalingControl = FindMarshalingControl();
if (!marshalingControl.IsHandleCreated) {
return false;
}
hwnd = new HandleRef(marshalingControl, marshalingControl.Handle);
}
int pid;
int hwndThread = SafeNativeMethods.GetWindowThreadProcessId(hwnd, out pid);
int currentThread = SafeNativeMethods.GetCurrentThreadId();
return(hwndThread != currentThread);
}
}
}
Which clearly shows that each time you get the property value it specifically checks the thread that it is running on. If it's the UI thread, it returns false, if not it returns true.
Which means that the two calls are being made from different threads: one from a non-UI thread, and the second from a UI thread.
So you need to check exactly when that code is being executed, and what event caused it to execute - we can't do that!
Me? I'd check once if an invoke was required, and if so invoke the current method instead of checking repeatedly and duplicating code!