Ответ 1
this.Invoke(new Action(() => { MessageBox.Show(this, "text"); }));
Это переключится на основной поток и покажет MessageBox с родителем form1
.
После нажатия button1
, помещенного в form1
, программа проверяет, доступна ли новая версия (через Интернет), но делает это в новом потоке (чтобы не заморозить форму во время проверки).
Когда новая версия найдена или нет, отображается соответствующая MessageBox
, но у нее нет родительского элемента (потому что она была вызвана из потока, а не непосредственно из form1
).
Как сделать отображение MessageBox
с form1
в качестве родителя?
this.Invoke(new Action(() => { MessageBox.Show(this, "text"); }));
Это переключится на основной поток и покажет MessageBox с родителем form1
.
В то время как выбранный ответ обеспечивает хороший способ отображения MessageBox
из асинхронного потока, он не обрабатывает случай, когда вы хотите извлечь DialogResult
из показанного MessageBox
.
Если вы хотите вернуть DialogResult
из вызываемого MessageBox
, отображаемого поверх Form
. Затем вам нужно использовать делегат Func
вместо делегата Action
.
Action
делегаты всегда возвращают void, а Func
имеет возвращаемое значение.
Вот небольшой метод, который я разработал для обработки этого конкретного сценария:
private DialogResult BackgroundThreadMessageBox(IWin32Window owner, string text)
{
if (this.InvokeRequired)
{
return (DialogResult) this.Invoke(new Func<DialogResult>(
() => { return MessageBox.Show(owner, text); }));
}
else
{
return MessageBox.Show(owner, text);
}
}
Хотя это обычно не считается лучшей практикой или дизайном, он будет работать в крайнем случае.
if ( Form1.InvokeRequired ) {
Form1.Invoke((Action)delegate{MessageBox.Show(Form1,"Hello");});
}
Попробуйте использовать backgroundworker.
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
//Helper thread: Long during task
}
private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//We're in the main thread: Show your messagebox
}
В моем случае я был в другом классе и имел ссылку для текстового поля, поэтому я использовал следующий код:
_txtResultado.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate ()
{
MessageBox.Show("My message!");
}));