当前位置:  开发笔记 > 编程语言 > 正文

Invoke()和BeginInvoke()之间有什么区别

如何解决《Invoke()和BeginInvoke()之间有什么区别》经验,为你挑选了6个好方法。

只是想知道BeginInvoke()和之间的区别Invoke()是什么?

主要是每个人将用于什么.

编辑:创建一个线程对象和调用invoke并只调用BeginInvoke()一个委托有什么区别?或者他们是一样的吗?



1> Jon Skeet..:

你的意思是Delegate.Invoke/BeginInvoke还是Control.Invoke/BeginInvoke?

Delegate.Invoke:在同一个线程上同步执行.

Delegate.BeginInvoke:在线程池线程上异步执行.

Control.Invoke:在UI线程上执行,但调用线程在继续之前等待完成.

Control.BeginInvoke:在UI线程上执行,调用线程不等待完成.

蒂姆的回答提到你可能想要使用BeginInvoke - 尽管它主要面向Delegate.BeginInvoke,我怀疑.

对于Windows窗体应用程序,我建议您通常应该使用BeginInvoke.这样你就不必担心死锁了 - 但是你需要明白,在你下次看它时,UI可能还没有更新!特别是,您不应该修改UI线程可能用于显示目的的数据.例如,如果您有具有FirstName和LastName属性的Person,并且您执行了以下操作:

person.FirstName = "Kevin"; // person is a shared reference
person.LastName = "Spacey";
control.BeginInvoke(UpdateName);
person.FirstName = "Keyser";
person.LastName = "Soze";

然后UI可能最终显示"Keyser Spacey".(外面的机会可以显示"Kevin Soze",但只能通过记忆模型的怪异.)

但是,除非你遇到这种问题,否则Control.BeginInvoke更容易正确,并且会避免你的后台线程无需等待.请注意,Windows窗体团队已经保证您可以以"即发即忘"的方式使用Control.BeginInvoke - 即无需调用EndInvoke.对于异步调用一般情况并非如此:通常每个BeginXXX都应该有相应的EndXXX调用,通常在回调中.


@SharpUrBrain:Control.BeginInvoke等同于Dispatcher.BeginInvoke,但是对于WinForms(而Dispatcher用于WPF和Silverlight).
那为什么ppl会使用Invoke而不是BeingInvoke?与使用Invoke相比,不应该有一些优势.两者都在后台执行进程,只是一个在同一个线程上,另一个在不同的线程上?
@SharpUrBrain:我建议你提出一个具体的问题而不是继续评论 - 当然要先检查一下是否已经有人问过同一个问题.
@Jon:当我使用Dispatcher.BeginInvoke时,我的代码工作正常并且在Dispatcher中.我的应用程序让我等待几秒钟然后它初始化所有控件然后启动,你能帮我找出我卡住了哪个地方?

2> Tim Stewart..:

在Jon Skeet的回复基础上,有时您想要调用委托并等待其执行在当前线程继续之前完成.在这些情况下,Invoke调用就是你想要的.

在多线程应用程序中,您可能不希望线程等待委托完成执行,特别是如果该委托执行I/O(这可能使委托和您的线程阻塞).

在这些情况下,BeginInvoke会很有用.通过调用它,您告诉委托人开始,然后您的线程可以自由地与委托并行执行其他操作.

使用BeginInvoke会增加代码的复杂性,但有时候改进的性能值得复杂.



3> Sujit..:

Control.Invoke()和之间的区别Control.BeginInvoke()是,

BeginInvoke()将在GUI线程上安排异步操作.安排异步操作后,代码将继续.一段时间后(您不确切知道何时)将执行您的异步操作

Invoke() 将执行您的异步操作(在GUI线程上)并等待您的操作完成.

一个合乎逻辑的结论是,您传递给的委托Invoke()可以具有out-parameters或return-value,而传递给的委托BeginInvoke()则不能(您必须使用EndInvoke来检索结果).



4> KMC..:

只是给出一个简短的,有效的例子来看看它们之间的差异

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会同时弹出文本更新.如果使用Invoke,MessageBox会在3秒睡眠后弹出.因此,显示异步(BeginInvoke)和同步(Invoke)调用的效果.



5> Aaron Palmer..:

Delegate.BeginInvoke()以异步方式对委托的调用进行排队,并立即返回控制.使用Delegate.BeginInvoke()时,应该在回调方法中调用Delegate.EndInvoke()来获取结果.

Delegate.Invoke()在同一个线程中同步调用委托.

MSDN文章



6> Ingako..:

只需添加使用Invoke()的原因和时间.

Invoke()和BeginInvoke()都将您指定的代码封送到调度程序线程.

但与BeginInvoke()不同,Invoke()会停止您的线程,直到调度程序执行您的代码.如果需要暂停异步操作,直到用户提供某种反馈,您可能希望使用Invoke().

例如,您可以调用Invoke()来运行显示"确定/取消"对话框的代码片段.在用户单击按钮并且您的编组代码完成后,invoke()方法将返回,您可以根据用户的响应进行操作.

请参阅C#第31章中的Pro WPF

推荐阅读
可爱的天使keven_464
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有