我有一个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
正确的方法是:
- 等待所有任务完成后再转到下一批?
- 在每个任务完成时用总体进度更新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