在等待任务完成时更新UI



我有一个vb.net应用程序处理大量的数据。由于进程的内存需求,我以批处理方式执行此操作,总体规划结构如下:

Do while Start < TotalNumberOfObjects
    [cache data used for the upcoming batch]
    For i = Start to Stop
        [process data using multiple tasks...for example:]
        t=taskfactory.startnew(doStuff(i))
        TaskList.TryAdd(t.ContinueWith(Sub()                                      
                                         Me.BeginInvoke(DelegateUpdateProgress, {progress})
                                       End Sub))
    Next
    [Wait for tasks to complete...
    Normally I would wait for the tasks using task.waitall(), 
    but this will cause the UI to wait to update until all tasks are complete]
    Start = Stop+1
    Stop = Stop+Increment
    [clear data from batch that was just completed]
loop

正确的方法是:

  1. 等待所有任务完成后再转到下一批?
  2. 在每个任务完成时用总体进度更新UI ?

我的目标框架是。net 4.0

感谢您的建议。

编辑:目前我正在使用task.continuewith()完成每个任务并调用me.beginInvoke更新表单后更新UI,

TaskList.TryAdd(t.ContinueWith(Sub()                                      
                                 Me.BeginInvoke(DelegateUpdateProgress, {progress})
                               End Sub))

然而,这与我期望等待任务列表完成的方式不兼容,task.waitall(tasklist)因为调用task.waitall将导致UI线程等待更新,直到所有任务完成。

首先需要设置一个委托,然后使用Dispatcher。调用

在下面的例子中,按钮从启用变为禁用(或相反):

   Delegate Sub SetRecordButtonEnabledCallback(ByVal Enabled As Boolean)
   Friend Sub SetRecordButtonEnabled(ByVal Enabled As Boolean)
        Me.btnDGRecord.IsEnabled = Enabled
   End Sub
之后,您需要做的就是在计时器内调用以下代码来调用它:

将DesiredValue设置为Boolean = True

Me.Dispatcher。调用(New SetRecordButtonEnabledCallback(addressofsetrecordbuttonenabled), New对象(){DesiredValue})

为什么不把你的例程放在一个Backgroundworker结构中呢?

所以,当你编码处理数据时,你已经准备好更新任何UI组件了。

如果有必要,你也可以从Backgroundworker更新UI,但你需要有一些特殊的要求来做到这一点。

您可以在这里查阅:https://msdn.microsoft.com/en-us//library/ywkkz4s1.aspx

最新更新