适用于从多个线程更新进度条的模式(使用TPL?)

时间:2013-06-07 17:31:03

标签: vb.net multithreading winforms progress-bar task-parallel-library

我一直忙于用TPL更新我的大脑,因为我打算将它用于我的新应用程序(使用.Net Framework 4.0)。但是我怀疑有人可能会为我澄清。以前,我有一个进度表单,在我启动需要显示其进度的线程后,我将从主(GUI)线程启动。它看起来像这样:

sortThread = New Thread(AddressOf _Sorter.Sort())
_ProgressForm = New FrmProgress()
_Sorter.ProgressForm = _ProgressForm
sortThread.Start()
progressForm.ShowDialog()

基本上它会初始化线程,初始化一个FrmProgress表单对象并将其分配给Sorter对象,然后Sorter对象将从单独线程上的Sort()子更新进度表(包含进度条和一些标签)。通过检查FrmProgress表单的InvokeRequired属性来更新这些控件属性,如果需要,它将使用要更新的控件的Invoke()方法...例如:

Public Sub IncrementProgressBar(x As Integer)
   If Me.InvokeRequired Then
      pb_MainProgressBar.Invoke(Sub() IncrementProgressBar(x))
   Else
      pb_MainProgressBar.Increment(x)
   End If    
End Sub

现在我有兴趣使用TPL启动可能想要更新进度条的单独工作线程(多个)。我应该使用相同的模式还是应该考虑访问在主GUI线程中获得的公共TaskScheduler.FromCurrentSynchronizationContext上下文?在这两种情况下,我想我应该在表单上提供某种锁定机制(SyncLock?)

1 个答案:

答案 0 :(得分:1)

调用就足够了,就像你在做的那样。如果两个不同的线程尝试并行调用,则第一个将首先执行,然后在UI线程空闲时执行第二个。 UI线程无法同时为两个调用提供服务 - 它们自然以FIFO顺序处理,因此线程安全没有问题。任何数量的线程都可以在主线程上调用,而不必担心彼此或使用任何其他锁定机制。

但请注意,任何调用Invoke的线程都将阻塞,直到主线程可以为该调用提供服务。例如,如果你有许多线程同时调用繁重的代码,那么你的各种线程会阻止调用调用,直到他们得到了他们的反应,可以这么说。如果使用BeginInvoke,则调用线程将继续执行,并且调用的方法将被放置在UI线程的队列中(它将尽快为其服务)。