我有一個代碼可以爲2000多家公司啓動下載數據例程。爲了簡化這個例子,我已經將下載例程改爲300秒。以下是由調用者多次調用的單個公司的例程。限制任務數
Public Async Function DoJob(ByVal company As Company) As Task(Of Boolean)
Console.WriteLine(String.Format("Started:{0}", company.CompanySymbol))
For i As Long = 1 To 300
Await Task.Delay(1000).ConfigureAwait(False)
Next
Console.WriteLine(String.Format("Ended:{0}", company.CompanySymbol))
Return True
End Function
從來電,我使用:
Dim downloadTasksQuery As IEnumerable(Of Task(Of Boolean)) =
From company In companies Select DoJob(company)
'***Use ToList to execute the query And start the download tasks.
Dim downloadTasks As IEnumerable(Of Task(Of Boolean)) = downloadTasksQuery.ToList()
Await Task.WhenAll(downloadTasks)
這裏做的事情是在平行火災所有的任務和任務得以排隊,直到它到達互聯網和具有回一個響應。由於任務數量很大,很多任務都會超時,因爲在任何時間點等待此類響應的任務數量巨大,因此他們無法在此時間內獲得響應。 (請記住,我已經刪除了實際的下載代碼以使事情變得簡單,並由長時間運行的任務代替,這些任務僅在上面的DoJob方法中等待300秒)。
我想要做的是限制了可以發射任務的數量。說,50.這意味着在任何時間點上只有50個任務會被激活,其餘的任務將等待50個任務完成,然後在任務完成時排隊。
我已經試過這樣:
Dim options As New ParallelOptions()
options.MaxDegreeOfParallelism = 100
Parallel.ForEach(companies, options, Sub(company)
' logic
DoJob(company)
End Sub)
但是看起來這是射擊的所有任務一氣呵成,而不是100,然後再等待(從DoJob
的印刷品來爲所有2000+的項目,然後任務完成)。
同樣在這裏的問題太多:
Dim listOfActions = New List(Of Action)()
For Each company In companies
' Note that we create the Action here, but do not start it.
listOfActions.Add(Function() DoJob(company))
Next
Dim options As New ParallelOptions()
options.MaxDegreeOfParallelism = 100
Parallel.Invoke(options, listOfActions.ToArray())
我已經試過@ClearLogics例如How to limit the Maximum number of parallel tasks in c#
它也呈現出相同的行爲。所有任務立即被解僱。
如何解決這個問題 - 只需要火100個任務等待隨後保持在任何時候排隊,這樣,我沒有超過100個任務。
[限制通過並行任務庫運行的活動任務數量的最佳方法]的可能重複(https://stackoverflow.com/questions/11138927/best-way-to-limit-the-number-of-主動任務運行,通過最並行任務天秤座) – cassandrad