调用和BeginInvoking MessageBox有什么区别?

maf*_*afu 12 .net c# messagebox winforms

在表格中,比较

BeginInvoke (new Action (() => {
    MessageBox.Show ());
}));
Run Code Online (Sandbox Code Playgroud)

Invoke (new Action (() => {
    MessageBox.Show ());
}));
Run Code Online (Sandbox Code Playgroud)

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

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

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

Jef*_*tes 16

BeginInvoke 将异步调用委托,立即返回将委托排队等待执行独立于当前线程.

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

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

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

Invoke(new Action(()=>Console.WriteLine("Invoke")));
Console.WriteLine("AfterInvokeCalled");
Run Code Online (Sandbox Code Playgroud)

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

AfterBeginInvokeCalled
调用
AfterInvokeCalled
BeginInvoke

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


Dan*_*Tao 14

西蒙其实没错.

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

Invoke就像在说:" 现在就这样做.我会等."

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

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

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