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