Вызовите MessageBox из асинхронного потока с Form1 как родительский

После нажатия button1, помещенного в form1, программа проверяет, доступна ли новая версия (через Интернет), но делает это в новом потоке (чтобы не заморозить форму во время проверки).
Когда новая версия найдена или нет, отображается соответствующая MessageBox, но у нее нет родительского элемента (потому что она была вызвана из потока, а не непосредственно из form1).

Как сделать отображение MessageBox с form1 в качестве родителя?

Ответы

Ответ 1

this.Invoke(new Action(() => { MessageBox.Show(this, "text"); }));

Это переключится на основной поток и покажет MessageBox с родителем form1.

Ответ 2

В то время как выбранный ответ обеспечивает хороший способ отображения 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);
   }
}

Хотя это обычно не считается лучшей практикой или дизайном, он будет работать в крайнем случае.

Ответ 3

  if ( Form1.InvokeRequired ) {
            Form1.Invoke((Action)delegate{MessageBox.Show(Form1,"Hello");});
        }

Ответ 4

Попробуйте использовать 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
}

Ответ 5

В моем случае я был в другом классе и имел ссылку для текстового поля, поэтому я использовал следующий код:

_txtResultado.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate ()
{
    MessageBox.Show("My message!");
}));