I'm executing a code in a worker thread. Sometimes, I need to show a dialog or a Message.
I have been playing with the code and only seems to be strictly necesary to Invoke
when I pass a IWin32Window
to the dialog. Otherwise works fine.
My questions are two:
Invoke
?Thanks in advance
It is a bit of a bug in Winforms. It contains diagnostic code in the Handle property getter that verifies that the property is used in the same thread as the one that created the handle. While extremely helpful to diagnose threading bugs, that is not always appropriate. One such case is here, Windows doesn't actually require that the parent of a window is owned by the same thread.
You can work around it by pinvoking SetParent() or by temporarily disabling checking with Control.CheckForIllegalCrossThreadCalls. Or by using Control.Invoke(), the best way. Do not work around it by not specifying the owner. For lack of another window, the dialog's owner is the desktop window. It will have no Z-order relationship with the other windows that have the desktop as their owner. And that will make the dialog disappear behind another window occasionally, completely undiscoverable by the user.
There's a bigger problem though, displaying dialogs on threads is a nasty usability problem. Shoving a window into the user's face while she's working with your program is an all-around bad idea. There's no telling what will happen when she's busy clicking and typing. Her accidentally closing the dialog without even seeing it is a real danger. Don't do it.
If you are not specifying the owner of the MessageBox
it will work because it doesn't rely on the form UI thread.
I think it is safe to call it without using Invoke
if you are not aware of showing as a dialog to specific form.
Edit: To test it, the following code just creating a new thread and show message box from it where at UI thread creating a second message at the same time with specifying the owner to be the form, both messages shows up without any problem:
private void button1_Click(object sender, EventArgs e)
{
new Thread(() =>
{
MessageBox.Show("Hello There!");
}) { IsBackground = true }.Start();
Thread.Sleep(1000);
if (MessageBox.Show(this, "Hi", "Jalal", MessageBoxButtons.YesNo) ==
System.Windows.Forms.DialogResult.Yes)
{
return;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With