What is the difference between Invoking and BeginI

2020-02-22 05:37发布

In a form, compare

BeginInvoke (new Action (() => {
    MessageBox.Show ());
}));

with

Invoke (new Action (() => {
    MessageBox.Show ());
}));

What is the difference, and when should I use one over the other? How is the behavior affected by the message pump of the MessageBox?

I did some testing and found that both methods block the UI.

The only difference is that Invoke is actually called instantly while BeginInvoke takes a (very short) time until the code is run. This is to be expected.

5条回答
兄弟一词,经得起流年.
2楼-- · 2020-02-22 06:26

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.

查看更多
三岁会撩人
3楼-- · 2020-02-22 06:27

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.

查看更多
不美不萌又怎样
4楼-- · 2020-02-22 06:36

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.

查看更多
Animai°情兽
5楼-- · 2020-02-22 06:41

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.

查看更多
男人必须洒脱
6楼-- · 2020-02-22 06:43

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.

查看更多
登录 后发表回答