VB.Net实现固定最大并发数的滚动式任务执行方案咨询
VB.Net 实现固定最大并发数的任务调度
你当前的批次执行方案存在效率瓶颈:必须等整批任务全部完成才能启动下一批,若批次内有耗时久的任务,会拖慢整体进度。要实现始终保持指定最大并发数,完成一个任务就立即启动新任务的需求,VB.Net里有两种简洁可靠的实现方式:
方案一:使用SemaphoreSlim手动控制并发
SemaphoreSlim可以限制同时执行的任务数量,每个任务启动前先获取信号量,完成后释放,自动补位新任务。
Dim semaphore As New SemaphoreSlim(_batchsize) ' _batchsize为设定的最大并发数 Dim tasks As New List(Of Task)() For Each dr As DataRow In tbl.Rows ' 超过并发数时自动等待,直到有任务释放信号量 semaphore.Wait() Dim threadData As New processThreadData() threadData.code = stuff threadData.otherStuff = moreStuff Dim task = Task.Run(Async Function() Try Await Task.Run(Function() MyFunction(threadData)) ' 执行任务逻辑 Finally ' 任务完成必须释放信号量,避免死锁 semaphore.Release() End Try End Function) tasks.Add(task) Next ' 等待所有任务执行完毕 Await Task.WhenAll(tasks) ' 若需同步等待可替换为:Task.WaitAll(tasks.ToArray())
方案二:使用ActionBlock(基于TPL Dataflow,推荐)
TPL Dataflow的ActionBlock可直接指定MaxDegreeOfParallelism,内部自动管理并发逻辑,代码更简洁。
首先需引用System.Threading.Tasks.Dataflow NuGet包,再编写代码:
' 创建ActionBlock并设置最大并发数 Dim actionBlock As New ActionBlock(Of DataRow)( Async Sub(dr) Dim threadData As New processThreadData() threadData.code = stuff threadData.otherStuff = moreStuff Await Task.Run(Function() MyFunction(threadData)) ' 执行任务逻辑 End Sub, New ExecutionDataflowBlockOptions With { .MaxDegreeOfParallelism = _batchsize ' 设定最大并发数 } ) ' 将所有数据行送入任务队列 For Each dr As DataRow In tbl.Rows actionBlock.Post(dr) Next ' 标记队列不再接受新任务,等待所有任务完成 actionBlock.Complete() Await actionBlock.Completion ' 同步等待可替换为:actionBlock.Completion.Wait()
注意事项
- 若在UI线程使用同步等待(
Wait/WaitAll),需注意避免死锁,优先推荐异步等待(Await)。 - 若
MyFunction本身是异步方法,可直接调用无需用Task.Run包装。
内容的提问来源于stack exchange,提问作者Tym
相关产品推荐
相关产品推荐

