只是想知道BeginInvoke()
和Invoke()
之间的区别是什么?
主要是每一个都是用来做什么的.
编辑:创建一个线程对象,并对其调用invoke,与对一个委托调用BeginInvoke()
有什么区别?或者他们是同一件事?
只是想知道BeginInvoke()
和Invoke()
之间的区别是什么?
主要是每一个都是用来做什么的.
编辑:创建一个线程对象,并对其调用invoke,与对一个委托调用BeginInvoke()
有什么区别?或者他们是同一件事?
你是说Delegate.Invoke
/BeginInvoke
还是Control.Invoke
/BeginInvoke
?
Delegate.Invoke
:在同一线程上同步执行.Delegate.BeginInvoke
:在threadpool
线程上异步执行.Control.Invoke
:在UI线程上执行,但调用线程等待完成后再继续.Control.BeginInvoke
:在UI线程上执行,调用线程不等待完成.蒂姆的答案提到了什么时候你可能想要使用BeginInvoke
--尽管我怀疑它主要是针对Delegate.BeginInvoke
的.
对于Windows窗体应用程序,我建议您使用usually使用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".(它显示"凯文·苏斯"的可能性很小,但只有通过记忆模型的怪异才行.)
然而,除非你有这样的问题,否则Control.BeginInvoke
更容易得到正确的答案,并且可以避免你的后台线程无需等待任何好的理由.请注意,Windows窗体团队已保证,您可以以"开火并忘记"的方式使用Control.BeginInvoke
,即不必拨打EndInvoke
.一般来说,异步调用不是这样的:通常每个BeginXXX都应该有一个对应的EndXXX调用,通常在回调中.