I encounter a problem with a Windows Forms application.
A form must be displayed from another thread. So in the form class, I have the following code:
private delegate void DisplayDialogCallback();
public void DisplayDialog()
{
if (this.InvokeRequired)
{
this.Invoke(new DisplayDialogCallback(DisplayDialog));
}
else
{
this.ShowDialog();
}
}
Now, every time I run this, an InvalidOperationException
is thrown on the line this.ShowDialog();
:
"Cross-thread operation not valid: Control 'SampleForm' accessed from a thread other than the thread it was created on."
What's wrong with this piece of code? Isn't it a valid way to make cross-thread calls? Is there something special with ShowDialog()
?
Try this one:
private delegate void DisplayDialogCallback();
public void DisplayDialog()
{
if (this.InvokeRequired)
{
this.Invoke(new DisplayDialogCallback(DisplayDialog));
}
else
{
if (this.Handle != (IntPtr)0) // you can also use: this.IsHandleCreated
{
this.ShowDialog();
if (this.CanFocus)
{
this.Focus();
}
}
else
{
// Handle the error
}
}
}
Please note that InvokeRequired
returns
true if the control's Handle was created on a different thread than the calling thread (indicating that you must make calls to the control through an invoke method); otherwise, false.
and therefore, if the control has not been created, the return value will be false
!