我应该使用Invoke或SynchronizationContext来更新另一个线程的表单控件吗?

时间:2011-09-20 05:01:44

标签: c# multithreading invoke

尝试从其他线程更新UI控件。

目前正在使用BeginInvoke,老实说它工作正常,但我一直听说你如何使用SynchronizationContext来做同样的事情。

哪个更受欢迎?

另外,从线程更新UI是不好的做法吗?提出一个事件并让主要形式处理它或者还有其他更好的方法来做这件事会更好吗?

对于这个有点主观的问题感到抱歉,但是在线程领域有很多选择,我正在努力把握它们之间的差异以及它们各自适用的位置,以及为将来编写可读和可扩展代码的最佳实践

编辑:此外我现在也看到了TaskScheduler.FromCurrentSynchronizationContext路线..有很多选择x_x

2 个答案:

答案 0 :(得分:6)

我更喜欢SynchronizationContext而不是Control.InvokeControl.Invoke的危险在于拥有Control的生命周期问题。如果控件在您尝试Invoke时处理掉,则会影响调用成功的能力。当对话框关闭,视图移位等时会发生这种情况......

SynchronizationContext.Current虽然通常与它关联的线程一直存在。它确实具有有限的寿命,因此最终存在相同的问题,但它比Control更具可预测性。

答案 1 :(得分:0)

您是否考虑过使用Background Worker组件?对于不应该占用UI的长时间运行任务,它是获得多线程功能的简洁方法。例如,您可以使用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