我应该使用Invoke或SynchronizationContext来更新另一个线程的表单控件吗?
试图从其他线程更新UI控件。
目前正在使用BeginInvoke,老实说它工作正常,但我一直听说你如何使用SynchronizationContext来做同样的事情。
哪个更受欢迎?
另外,从线程更新UI是不好的做法吗? 提出一个事件并让主要forms处理它或者还有其他更好的方法来做这件事会更好吗?
对于这个有点主观的问题感到抱歉,但是在线程领域有很多选择,我正在努力把握它们之间的差异以及它们各自适用的位置,以及为将来编写可读和可扩展代码的最佳实践。
编辑:现在我也看到还有TaskScheduler.FromCurrentSynchronizationContext
路由..这么多选择x_x
我更喜欢SynchronizationContext
不是Control.Invoke
。 Control.Invoke
的危险在于拥有Control
存在生命周期问题。 如果在您尝试Invoke
控件时处置控件,则会影响调用成功的能力。 当对话框关闭,视图移动等时会发生这种情况……
SynchronizationContext.Current
虽然通常与它关联的线程一样长。 它确实具有有限的寿命,因此最终存在相同的问题,但它比Control
更可预测。
您是否考虑过使用Background Worker组件? 对于不应该占用UI的长时间运行任务,它是获得multithreadingfunction的简洁方法。 例如,您可以使用ProgressChanged事件对UI执行更新,后台工作程序和后台工作者类将确保创建BW的线程是执行ProcessChanged和WorkComplete事件的线程。 因此,如果您从UI创建BW并将其设置为工作,那么您可以从那里安全地更新UI。
这是来自MS的快速文章http://msdn.microsoft.com/en-us/library/cc221403%28v=vs.95%29.aspx
另一个非常好的链接http://www.albahari.com/threading/part3.aspx#_BackgroundWorker