finch
finch

Reputation: 549

How to Invoke MessageBox on background thread in VB.NET?

How do I call Invoke to run MessageBox.Show on my background thread please?

When I display a MessageBox on my single background thread, it usually displays behind the main form, so to make the program usable I need to display it in front of the main form.

My current code is MessageBox.Show(myMessageText, myTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation) without owner. This code is not called from the form itself. but from a helper class I have built outside it.

I want to add an owner to the MessageBox on my background thread, so am seeking run this code: MessageBox.Show(myOwnerForm, myMessageText, myTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

At the point I want to run this, myOwnerForm.InvokeRequired returns true, so I know I need to call an invoke method. But how? (If I just call this code, I get an exception, which is widely documented elsewhere). As the MessageBox should stop processing on the UI too, I want to use Invoke, not BeginInvoke.

How can I use invoke to run Messagebox.Show?

After hours looking on StackOverflow and elsewhere, I can only see partial solutions.

My app uses Windows Forms, developed in VB.NET using Visual Studio 2010.

Upvotes: 0

Views: 7102

Answers (1)

keenthinker
keenthinker

Reputation: 7820

The Invoke method takes a delegate (callback function) that is called and optionally any parameters. Quote from MSDN:

Executes the specified delegate on the thread that owns the control's underlying window handle.

  • pack the MessageBox in a method
  • create a delegate (method with the same signature as your message box method)
  • call the delegate with Invoke

Example code (Me.Invoke can be changed to someControl.Invoke):

Delegate Sub MyDelegate(ByVal msg As String)

Private Sub ButtonStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonStart.Click

    'If Control.InvokeRequired Then
    Dim parameters(0) As Object
    parameters(0) = "message"
    Me.Invoke(New MyDelegate(AddressOf showMessage), New Object() {"message"})
    'End If

End Sub

Private Sub showMessage(ByVal msg As String)
    MessageBox.Show(msg, "test", MessageBoxButtons.OK)
End Sub

As many of the commentators already said, it is a bad practise to have / execute UI in / from thread (interacting with the user). If you need a MessageBox shown to the user when an event occurs in the thread, then create/use some messaging system.

Upvotes: 1

Related Questions