Из консольного приложения, в котором нет окна (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.
Application.Run()
. Таким образом, вы получаете приложение, которое не показывает интерфейс, если вы этого не хотите, и оно не завершится, если вы явно не убьете его из кода. Пример здесь. - person Idle_Mind   schedule 23.12.2020