使用Invoke和SynchronizationContext.Post对象有什么区别?

8
当我收到与线程上下文相关的异常时,我使用委托函数并调用此委托函数。这对于从其他线程控制是必要的。但我刚学到可以使用SynchronizationContext.Post()函数,并且可以在此方法中调用我的委托。
我不确定哪种方法更好?这些方法之间有什么区别?

你是使用委托的 Invoke 方法还是使用 Control.Invoke 方法来调用委托? - Hamlet Hakobyan
1
你应该将 SynchronizationContext.PostControl.BeginInvoke 进行比较,将 SynchronizationContext.SendControl.Invoke 进行比较。WinFormsSynchronizationContext 在内部调用 Control.BeginInvoke - noseratio - open to work
是的,我可以比较它们,但我想知道它们在理论上的区别。 - golazo
2个回答

20

SynchronizationContext.Post() 调用 BeginInvoke(), Send() 调用 Invoke(),作用相同。

SynchronizationContext 的关键属性是有不止一种实现方式。其中重要的实现方式有 WindowsFormsSynchronizationContext,它使用 Control.Begin/Invoke 和 DispatcherSynchronizationContext,它使用 Dispatcher.Begin/Invoke。还有其他的实现方式,适用于 ASP.NET、Windows Store(也称为 WinRT、通用应用程序)应用程序、COM+ 托管的外部进程服务器等。

这个额外的间接级别有助于避免对调用具体方法的依赖。当然,对于任何类库都很重要。


4
Control.Invoke等同于SynchronizationContext.Send,因为它们都是同步的Control.BeginInvoke等同于SynchronizationContext.Post,因为它们都是异步的。使用其中任何4种方法都可以防止跨线程异常。
使用SynchronizationContext来封装线程编组代码。例如,Form1创建对象Worker以在不同的线程上执行某些工作。 Worker的构造函数捕获当前(即Form1的)SynchronizationContext。当Worker生成要在Form1上显示的数据时,Worker可以使用捕获的SynchronizationContext在发送通知(例如事件)到Form1之前同步到Form1的线程。这意味着Form1不需要知道不同的线程,也不需要调用InvokeRequired,并且有较少的代码。这也意味着Worker不需要知道其客户端是表单。
下面是一个绝妙的系列,解释了SynchronizationContext的含义: 了解SynchronizationContext - Part I 了解SynchronizationContext - Part II 了解SynchronizationContext - Part III

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接