Invoke()和BeginInvoke()之间有什么区别
只是想知道BeginInvoke()
和Invoke()
之间的区别是什么?
主要是每一个将被用于什么。
编辑:创build一个线程对象和调用该调用,只是调用BeginInvoke()
上的BeginInvoke()
之间有什么区别? 还是他们是一样的东西?
你的意思是Delegate.Invoke / BeginInvoke或Control.Invoke / BeginInvoke?
- Delegate.Invoke:在同一个线程上同步执行。
- Delegate.BeginInvoke:在线程池线程上asynchronous执行。
- Control.Invoke:在UI线程上执行,但在继续之前调用线程等待完成。
- Control.BeginInvoke:在UI线程上执行,调用线程不会等待完成。
Tim的回答提到了你可能想要使用BeginInvoke–虽然它主要是面向Delegate.BeginInvoke,我怀疑。
对于Windows窗体应用程序,我build议你通常应该使用BeginInvoke。 那样的话,你就不用担心死锁了,但是你需要明白,下次看UI的时候用户界面可能不会被更新! 尤其是,您不应修改UI线程可能用于显示目的的数据。 例如,如果您拥有名字和姓氏属性的人员,并且您执行了以下操作:
person.FirstName = "Kevin"; // person is a shared reference person.LastName = "Spacey"; control.BeginInvoke(UpdateName); person.FirstName = "Keyser"; person.LastName = "Soze";
那么UI可能最终显示“Keyser Spacey”。 (有一个外部的机会,它可以显示“凯文Soze”,但只有通过记忆模型的怪异。)
除非你有这样的问题,然而,Control.BeginInvoke更容易得到正确的,并将避免你的后台线程不得不等待没有理由。 请注意,Windows窗体团队已经保证,您可以使用Control.BeginInvoke以“即忘即忘”的方式 – 即不调用EndInvoke。 通常情况下,asynchronous调用并不是这样:通常每个BeginXXX都应该有一个相应的EndXXX调用,通常在callback中。
基于Jon Skeet的回复,有时候你想要调用一个委托并等待它的执行完成,然后继续执行当前线程。 在这种情况下,Invoke调用是你想要的。
在multithreading应用程序中,您可能不希望线程等待委托来完成执行,特别是如果该委托执行I / O(这可以使委托和您的线程块)。
在这些情况下,BeginInvoke会很有用。 通过调用它,你告诉委托开始,但是你的线程可以自由地与委托并行地做其他事情。
使用BeginInvoke增加了代码的复杂性,但有时候改进的性能值得复杂化。
Control.Invoke()
和Control.BeginInvoke()
之间的区别是,
-
BeginInvoke()
将在GUI线程上安排asynchronous操作。 当计划asynchronous操作时,您的代码将继续。 一段时间后(你不知道什么时候)你的asynchronous操作将被执行 -
Invoke()
将执行你的asynchronous操作(在GUI线程上)并等到你的操作完成。
一个合乎逻辑的结论是,您传递给Invoke()
的委托可以有外部参数或返回值,而传递给BeginInvoke()
的委托不能(您必须使用EndInvoke来检索结果)。
只是给一个简短的工作示例,看看他们的差异的影响
new Thread(foo).Start(); private void foo() { this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate() { myTextBox.Text = "bing"; Thread.Sleep(TimeSpan.FromSeconds(3)); }); MessageBox.Show("done"); }
如果使用BeginInvoke ,MessageBox将同时popup文本更新。 如果使用Invoke ,则在3秒睡眠之后popup消息框。 因此,显示asynchronous( BeginInvoke )和同步( Invoke )调用的效果。
Delegate.BeginInvoke()asynchronous排队委托的调用,并立即返回控制。 当使用Delegate.BeginInvoke()时,您应该在callback方法中调用Delegate.EndInvoke()来获得结果。
Delegate.Invoke()在同一线程中同步调用委托。
MSDN文章
只需添加为什么以及何时使用Invoke()。
Invoke()和BeginInvoke()将您指定的代码编组到调度程序线程。
但是与BeginInvoke()不同,Invoke()会暂停你的线程,直到调度程序执行你的代码。 如果需要暂停asynchronous操作,直到用户提供某种反馈,则可能需要使用Invoke()。
例如,您可以调用Invoke()来运行显示“确定/取消”对话框的代码片段。 当用户点击一个button并且你的编组代码完成后,invoke()方法将返回,并且你可以对用户的响应进行操作。
请参阅C#第31章中的WPF
- 什么时候应该使用Tracing vs Logger.NET,Enterprise Library,log4net或Ukadc.Diagnostics?
- 为什么ReSharper想把“var”用于一切?
- 日志logging,面向方面的编程和dependency injection – 试图理解这一切
- .NET中的ManualResetEvent和AutoResetEvent有什么区别?
- C#中的双向/双向字典?
- 令人费解的Enumerable.Cast InvalidCastException
- 如何提取括号(圆括号)之间的文本?
- 将一个枚举属性数据绑定到WPF中的combobox
- entity framework太慢。 我有什么select?