我有一个Worker类和一个MainForm / UI类。在UI类中,我在新的后台线程中创建了一个Worker类的新实例。该线程将一些更新封送回UI的控件。因为它们在不同的类中,所以我基本上将MainForm实例(this)和一个适当的委托传递给工人类'构造函数。在构造函数中,我将mainForm设置为ISynchronizeInvoke
对象(称之为_synch),然后在worker类中{I} _synch.Invoke(theDelegate, new object[] { "new value" })
进一步向下。
一切正常,但后来我意识到也可以只做mainForm.Invoke
(不使用ISynchronizeInvoke
对象)。这两者有什么区别?
更糟糕的是,我在一篇文章中读到ISynchronizeInvoke
不再需要SynchronizationContext
,现在{{1}}已经过了很长时间。我意识到我不明白这两者是什么。任何有助于理解为什么我应该对这些对象使用Invoke而不是直接在mainForm上的帮助将不胜感激。
答案 0 :(得分:4)
在Winforms中,无论您拨打Form.Invoke
,ISynchronizeInvoke.Invoke
,SynchronizationContext.Send
的方法,您都在做同样的事情。
实际上它们都在内部使用Control.Invoke
(实现ISynchronizeInvoke
接口成员)的相同方法。
两者之间有什么区别(Form.Invoke和ISynchronizeInvoke.Invoke)?
没什么,他们指的是同一个方法Control.Invoke
。
那就是说,如果你依赖ISynchronizeInvoke
,当你将应用程序移植到另一种技术(比如WPF)时,你会感到痛苦。那里不支持ISynchronizeInvoke
。这是Winforms特有的东西。您应该始终支持SynchronizationContext
。
SynchronizationContext
提供抽象,无论技术如何,您都可以通过SynchronizationContext
封送对UI线程的调用(通常并非总是如此)。如果您的代码依赖于SynchronizationContext
,则可以轻松移植到WPF或Asp.Net,因为它们提供了SynchronizationContext的技术特定实现。
SynchronizationContext
的一个缺点是它无法获取返回值,但您可以通过闭包,实例成员等来解决它。