ISynchronizeInvoke vs SynchronizationContext vs mainForm.Invoke

时间:2014-09-24 15:11:57

标签: c# multithreading synchronization

我有一个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上的帮助将不胜感激。

1 个答案:

答案 0 :(得分:4)

在Winforms中,无论您拨打Form.InvokeISynchronizeInvoke.InvokeSynchronizationContext.Send的方法,您都在做同样的事情。

实际上它们都在内部使用Control.Invoke(实现ISynchronizeInvoke接口成员)的相同方法。

  

两者之间有什么区别(Form.Invoke和ISynchronizeInvoke.Invoke)?

没什么,他们指的是同一个方法Control.Invoke

那就是说,如果你依赖ISynchronizeInvoke,当你将应用程序移植到另一种技术(比如WPF)时,你会感到痛苦。那里不支持ISynchronizeInvoke。这是Winforms特有的东西。您应该始终支持SynchronizationContext

SynchronizationContext提供抽象,无论技术如何,您都可以通过SynchronizationContext封送对UI线程的调用(通常并非总是如此)。如果您的代码依赖于SynchronizationContext,则可以轻松移植到WPF或Asp.Net,因为它们提供了SynchronizationContext的技术特定实现。

  • Winforms实现--WindowsFormsSynchronizationContext
  • Wpf / Silverlight实现 - DispatcherSynchronizationContext
  • Asp.net实施 - AspNetSynchronizationContext

SynchronizationContext的一个缺点是它无法获取返回值,但您可以通过闭包,实例成员等来解决它。

进一步阅读:It's All About the SynchronizationContext