Dawid Moś
Dawid Moś

Reputation: 887

Call MessageBox from async thread with Form1 as parent

After clicking button1 placed on form1, program is checking if the new version is available (via internet), but doing this in the new thread (not to freeze the form during check).
When the new version is found or not, the appropriate MessageBox is shown, but it has no parent (because it was called from the thread, not directly from the form1).

How to make the MessageBox display with form1 as a parent?

Upvotes: 29

Views: 33610

Answers (5)

Ricardo França
Ricardo França

Reputation: 3003

In my case, I was in another class and had a reference for a textbox, so I used the code below:

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

Upvotes: 0

Derek W
Derek W

Reputation: 10046

While the selected answer provides a nice way of displaying the MessageBox from an asynchronous thread, it doesn't handle the case where you want to retrieve the DialogResult from that particular MessageBox being shown.

If you are looking to return a DialogResult from the invoked MessageBox displayed on top of the Form. Then you need to use the Func delegate instead of the Action delegate.

Action delegates always return void while Func has a return value.

Here is a little method that I devised to handle this particular scenario:

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);
   }
}

Although this isn't typically considered best practice or design it will work in a pinch.

Upvotes: 15

Stecya
Stecya

Reputation: 23276

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

This will switch to main thread and show MessageBox with form1 parent.

Upvotes: 54

Carra
Carra

Reputation: 17964

Try using a 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
}

Upvotes: -1

Arsen Mkrtchyan
Arsen Mkrtchyan

Reputation: 50752

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

Upvotes: 5

Related Questions