ISynchronizeInvoke vs SynchronizationContext vs ma

2019-09-03 19:18发布

I have a Worker class and a MainForm/UI class. From the UI class I create a new instance of the Worker class in a new background thread. This thread marshals a few updates back to the UI's controls. Since they are in different classes I basically pass the MainForm instance (this) and an appropriate delegate to update the controls, into the worker class' constructor. In the constructor I set the mainForm to an ISynchronizeInvoke object (call it _synch) and then, further down in the worker class I do _synch.Invoke(theDelegate, new object[] { "new value" }).

That all works fine, but then I realized that it is also possible to do just simply mainForm.Invoke (not using the ISynchronizeInvoke object). What is the difference between the two?

To make matters worse I read in an article that ISynchronizeInvoke is not really needed much anymore, now that SynchronizationContext has come a long. I realize that I do not understand what these two are for. Any help with understanding why I should use Invoke on these objects as opposed to directly on the mainForm would be greatly appreciated.

1条回答
SAY GOODBYE
2楼-- · 2019-09-03 19:54

In Winforms, No matter what method you call Form.Invoke, ISynchronizeInvoke.Invoke, SynchronizationContext.Send you are doing the same thing.

In fact they all internally goes to the same method which is Control.Invoke(which implements ISynchronizeInvoke interface member).

What is the difference between the two(Form.Invoke and ISynchronizeInvoke.Invoke)?

Nothing, they are pointing to same method Control.Invoke.

That said, if you depend on ISynchronizeInvoke you'll feel the pain when you're porting the application to another technology (say WPF). ISynchronizeInvoke is not supported there. It is the Winforms specific thing. You should always favour SynchronizationContext over anything.

SynchronizationContext provides the abstraction, whatever the technology may be, you can marshal the call to UI thread(typically not always) via SynchronizationContext. If your code depends on SynchronizationContext you can port to WPF or Asp.Net easily as they provide their technology specic implementation of SynchronizationContext.

  • Winforms implementation - WindowsFormsSynchronizationContext
  • Wpf/Silverlight implementation - DispatcherSynchronizationContext
  • Asp.net implementation - AspNetSynchronizationContext
  • Etc

One disadvantage of SynchronizationContext is that it provides no way to get the return value, though you can workaround it via closures, instance members etc.

Further reading: It's All About the SynchronizationContext

查看更多
登录 后发表回答