Should I call () to display a dialog or MessageBox from the stream?

I am executing code in a workflow. Sometimes I need to show a dialogue or message.

I played with the code, and it seems to me that this is necessary for Invoke when I pass IWin32Window in a dialog box. Otherwise, it works fine.

My questions are two:

  • Should I make a call?
  • What risks do I have if I show a dialogue or message without Invoke ?

Thanks in advance

+6
source share
3 answers

This is a bit of a mistake in Winforms. It contains the diagnostic code in the getter of the Handle property, which checks that the property is used in the same stream as the one that created the handle. Although it is extremely useful to diagnose errors in streaming mode, this is not always appropriate. One such case here, Windows does not actually require the parent of the window to belong to the same thread.

You can work around this by setting SetParent () or temporarily by disabling checking with Control.CheckForIllegalCrossThreadCalls. Or using Control.Invoke (), the best way. Do not work around without specifying the owner. Due to the absence of another window, the owner of the dialog box is the desktop window. It will not have Z-order relationships with other windows that have the desktop as their owner. And this will make the dialog disappear behind another window from time to time, completely unknown to the user.

There is a big problem, although displaying dialogs on threads is an unpleasant usability problem. Turning a window into the user's face when it works with your program is a bad idea. It does not say what will happen when she clicks and types. Her accidental closure of the dialogue, without even seeing it, poses a real danger. Do not do this.

+10
source

If you did not specify the owner of the MessageBox , it will work because it does not rely on the form user interface stream.
I think it's safe to call it without using Invoke if you don't know how to show the dialog in a specific form.

Edit:. To test it, the following code simply creates a new stream and displays a message box in which a second message is created in the user interface stream along with specifying the owner as a form, both messages are displayed without problems:

 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; } } 
+1
source

When I need to interact with some controls created in the main thread from another thread, I use BackgroundWorker. This event is called OnProgressChange. So, maeby try to create this BackgroundWorker object in the main thread, and in the DoWork method just run this event, then the method attached to it will be executed in the main thread, so you will get access to all the controls.

0
source

Source: https://habr.com/ru/post/894619/


All Articles