Почему вызов MessageBox.Show() влияет на видимость других форм (и потоков)?

Из консольного приложения, в котором нет окна (ProcessWindowStyle.Hidden), мне нужно запустить и отобразить форму (да, я знаю, что это плохой дизайн, которого следует избегать).

Моим первым намерением был следующий код:

var thread = new Thread(() =>
                            {
                                Application.EnableVisualStyles();
                                Application.SetCompatibleTextRenderingDefault(false);
                                Application.Run(new MyCustomMessageBoxForm());
                            });
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = false;
thread.Start();
thread.Join();

Это не работает: форма будет создана, но скрыта. Вам нужно вручную установить Visible на true, чтобы он работал должным образом (см. ответ Show Form из скрытого консольного приложения).

var thread = new Thread(() =>
                            {
                                Application.EnableVisualStyles();
                                Application.SetCompatibleTextRenderingDefault(false);
                                Application.Run(new MyCustomMessageBoxForm { Visible = true }); //Note the change
                            });
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = false;
thread.Start();
thread.Join();

Ни в ответе, ни у меня нет объяснения, почему вы должны явно устанавливать видимость — в «обычном» консольном приложении (с видимым консольным окном) это не требуется.

В любом случае, что меня больше озадачивает, так это то, что после вызова MessageBox.Show этот явный набор больше не требуется, чтобы заставить его работать - более того, не имеет значения, где в приложении вызывается MessageBox.Show (будь то тот же поток или нет). ), поэтому оба приведенных ниже примера работают должным образом:

MessageBox.Show("test"); // Note: called on other thread
var thread = new Thread(() =>
                            {
                                Application.EnableVisualStyles();
                                Application.SetCompatibleTextRenderingDefault(false);
                                Application.Run(new MyCustomMessageBoxForm()); //Works
                            });
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = false;
thread.Start();
thread.Join();

а также

var thread = new Thread(() =>
                            {
                                MessageBox.Show("test"); //Note: called on same thread
                                Application.EnableVisualStyles();
                                Application.SetCompatibleTextRenderingDefault(false);
                                Application.Run(new MyCustomMessageBoxForm()); //Works
                            });
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = false;
thread.Start();
thread.Join();

Итак, мой вопрос: почему это происходит - какие (поперечные!) побочные эффекты вызывает вызов MessageBox.Show?

Примечание. Я использовал .NET Framework, поведение может отличаться для .NET Core или .NET 5.


person BudBrot    schedule 23.12.2020    source источник
comment
Что-то вроде того, что MessageBox.Show() злой и запускает свой собственный насос сообщений и, возможно, больше, просто подождите Ханса Пассанта.   -  person CodeCaster    schedule 23.12.2020
comment
Из консольного приложения, в котором нет окна (ProcessWindowStyle.Hidden), мне нужно запустить и отобразить форму (да, я знаю, что это плохой дизайн, которого следует избегать). Значит, вам действительно не нужно консольное приложение? Используйте стандартное приложение WinFoms, но передайте собственное ApplicationContext на Application.Run(). Таким образом, вы получаете приложение, которое не показывает интерфейс, если вы этого не хотите, и оно не завершится, если вы явно не убьете его из кода. Пример здесь.   -  person Idle_Mind    schedule 23.12.2020
comment
Прочтите примечания здесь: Могу ли я отделить worker и GUI без исключений между потоками? (Консольное приложение с interactive< /i> Формы)   -  person Jimi    schedule 23.12.2020
comment
Кроме того, здесь и код здесь и здесь   -  person Jimi    schedule 23.12.2020