调用和BeginInvoking MessageBox有什么区别?

在表格中,比较

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

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

有什么区别,什么时候应该使用一个而不是另一个? 如何通过MessageBox的消息泵来影响行为?

我做了一些测试,发现两种方法都阻止了UI。

唯一的区别是Invoke实际上是立即调用的,而BeginInvoke需要(非常短的)时间直到代码运行。 这是可以预料的。

BeginInvoke将异步调用委托,立即返回将委托排队以便独立于当前线程执行。

Invoke将同步调用委托,阻塞调用线程,直到委托完成。

要查看差异,请尝试以下代码:

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

您应该看到类似于以下内容的输出,其中“BeginInvoke”文本由于其异步执行而延迟:

AfterBeginInvokeCalled
调用
AfterInvokeCalled
的BeginInvoke

关于您观察到的行为,因为它只是调用委托的同步或异步行为; 该方法的内容可能会导致调用线程停止或UI被阻止。 在显示消息框的情况下,无论委托是否使用BeginInvoke延迟,一旦调用委托,UI将被阻止,直到消息框被解除。

西蒙其实没错。

BeginInvoke就像向UI线程发送消息并说:“一旦有机会就这样做。”

Invoke就像是在说:“ 现在就这样做。我会等。”

澄清:只是因为你告诉 UI线程,“立即行动”,这并不意味着你是UI线程的上帝,并且可以强迫它放弃它正在做的一切。 基本上,上述陈述中的关键词是“我会等”。

问题是,在您的示例代码中,您发送到UI线程的消息是:调用MessageBox.Show 。 你猜怎么着? 这将阻止UI线程。

如果你想要注意BeginInvoke的异步行为,从一个单独的线程调用它,在代码中的BeginInvoke调用之后放置一个断点,并注意到即使在显示消息框时(并且UI被阻止),断点也会被命中。 如果您调用Invoke ,代码将不会继续,直到用户解除消息框。

BeginInvoke是异步的……这意味着调用线程不会等待被调用的方法返回。

好吧,对话框总是冻结GUI。 但是现在应该清楚begin invoke和invoke之间的区别:

调用等待被调用的方法返回BeginInvoke没有。

虽然大多数答案在技术上是正确的,但他们并没有提出明显的问题。

为什么要首先在Invoke / BeginOnvoke中包装MessageBox()调用?

Jeff解释说,在这种情况下使用BeginInvoke或Invoke没有任何好处。

听起来你在multithreading情况下在Windows窗体/控件上使用Invoke / BeginInvoke,在委托实例上使用Invoke / BeginInvoke(即异步编程模型)时感到困惑。

这很容易做,因为名称显然是相同的,但是您使用它们的场景和它们的行为是不同的。

CLR Via C#一书很好地解释了两种类型的Invoke / BeginInvoke。

对于MessageBox.Show,问题大多无关紧要。

唯一的区别是,使用BeginInvoke, 调用线程本身不会阻塞,因此它可以继续处理(清理,进一步处理等)。

UI线程显然会阻塞,因为会弹出一个模态窗口,等待用户输入关闭它。