我最近閱讀了一些使用TAP的文檔,特別是在較小標題「Task.WhenAny」下的this page。他們陳述4個主要目的爲Task.WhenAny:Task.WhenAny節流效率
- 冗餘
- 交錯
- 節流
- 早期救助
下方的交織(與間接地節流)小節他們有這樣的代碼
List<Task<Bitmap>> imageTasks =
(from imageUrl in urls select GetBitmapAsync(imageUrl)).ToList();
while(imageTasks.Count > 0)
{
try
{
Task<Bitmap> imageTask = await Task.WhenAny(imageTasks);
imageTasks.Remove(imageTask);
Bitmap image = await imageTask;
panel.AddImage(image);
}
catch{}
}
這個代碼不會很低效嗎?我假設一旦Task.WhenAll的第一個任務完成後,將列表中的其他任務設置爲「RanToCompletion」或「Cancelled」或其他一些可以終止其他任務進度的狀態。所以,即使在這個例子中列表中只有2個任務可以下載圖片,1個圖片是2MB,另一個是4MB,但2MB圖片可能會先完成(而2MB將會被接收) 。然後它會從列表中刪除2MB並啓動循環。這似乎會再次啓動4MB下載,實質上已經浪費了已經取得的進展,正確嗎?
爲什麼不寫一個代碼來測試你的假設?這通常是我理解一些概念的細節...... –
'WhenAny'將具有集合中提供的完成任務之一的結果,它不會將所有任務設置爲取消或完成。一旦它執行圖像操作,它將重複該循環並獲得下一張要添加的圖像。另一方面,WhenAll'將返回一個只有在完成指定任務時纔會完成的任務。 – ColinM
您可以隨時使用TPL DataFlow,其中包含** throttling **等功能。另外,TPL的流水線功能可以更好地服務於上面代碼的目的是想實現什麼 – MickyD