What is the difference between Invoking and BeginInvoking a MessageBox?

爱⌒轻易说出口 提交于 2019-11-30 04:05:23

BeginInvoke will invoke the delegate asynchronously, returning immediately having queued the delegate for execution independently of the current thread.

Invoke will invoke the delegate synchronously, blocking the calling thread until the delegate completes.

To see the difference, try the following code:

BeginInvoke(new Action(()=>Console.WriteLine("BeginInvoke")));
Console.WriteLine("AfterBeginInvokeCalled");

Invoke(new Action(()=>Console.WriteLine("Invoke")));
Console.WriteLine("AfterInvokeCalled");

You should see output similar to the following, where the "BeginInvoke" text is delayed due to its asynchronous execution:

AfterBeginInvokeCalled
Invoke
AfterInvokeCalled
BeginInvoke

Regarding the behaviour you observe, as it is only the act of calling the delegate that is synchronous or asynchronous; the content of the method may well cause the calling thread to stop or the UI to be blocked. In the case of showing a message box, regardless of whether the delegate is delayed using BeginInvoke or not, once the delegate is called, the UI will be blocked until the message box is dismissed.

Simon is actually not wrong.

BeginInvoke is like sending a message to the UI thread and saying, "Do this as soon as you get a chance."

Invoke is like saying, "Do this right now. I'll wait."

Clarification: just because you tell the UI thread, "Do this right now," that doesn't mean you are God of the UI thread and can force it to drop everything it's doing. Basically, the key words in the above statement are "I'll wait."

The thing is, in your example code, the message you're sending to the UI thread is: call MessageBox.Show. Guess what? That's going to block the UI thread either way.

If you want to notice the asynchronous behavior of BeginInvoke, call it from a separate thread, put a breakpoint after the BeginInvoke call in your code, and notice that the breakpoint gets hit even while the message box is displayed (and the UI is blocked). If you call Invoke, the code won't continue until the user dismisses the message box.

BeginInvoke is asynchronous... this means that the calling thread won't wait for the called method to return.

So ok, dialog box always freezes the GUI. But the difference between begin invoke and invoke should be now clear:

Invoke waits for the called method to return BeginInvoke does not.

While most of the answers are technically correct, they don't ask the obvious question.

Why do you want to wrap your MessageBox() calls in Invoke/BeginOnvoke in the first place?

There is simply no benefit in using BeginInvoke or Invoke in this situation, as Jeff explained.

It sounds like you're gettng confused between using Invoke/BeginInvoke on a windows form/control in a multi-threaded situation, and using Invoke/BeginInvoke on a delegate instance (ie the Asynchornous Programming Model).

This is easy to do as the names are obviously identical, however the scenarios you would use them and their behaviour is different.

The book CLR Via C# gives a good explanation of both types of Invoke/BeginInvoke.

For a MessageBox.Show, the question is mostly irrelevant.

The only difference is that with the BeginInvoke, the calling thread itself won't block, so it can continue doing things (cleanup, further processing, etc).

The UI thread will obviously block, because there's a modal window popped up waiting on user input to close it.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!