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
,代码将不会继续,直到用户解除消息框.