如何構建下面的代碼以便調用異步方法?如何正確使用異步方法編寫Parallel.For
Parallel.For(0, elevations.Count(), delegate(int i)
{
allSheets.AddRange(await BuildSheetsAsync(userID, elevations[i], includeLabels));
});
如何構建下面的代碼以便調用異步方法?如何正確使用異步方法編寫Parallel.For
Parallel.For(0, elevations.Count(), delegate(int i)
{
allSheets.AddRange(await BuildSheetsAsync(userID, elevations[i], includeLabels));
});
Parallel.For()
不async
方法很好地工作。如果您不需要限制並行度(即您可以同時執行所有任務),則可以簡單地啓動所有的Task
,然後等待它們完成:
var tasks = Enumerable.Range(0, elevations.Count())
.Select(i => BuildSheetsAsync(userID, elevations[i], includeLabels));
List<Bitmap> allSheets = (await Task.WhenAll(tasks)).SelectMany(x => x).ToList();
我無法添加它要求IEnnumerable的List
@ AlumCloud.Com啊,我沒有注意到'BuildSheetsAsync()'已經返回一個集合。如果你想從一個集合集合中創建一個集合,你可以使用'SelectMany()'。並且要從'IEnumerable'集合中創建一個列表,使用'ToList()'。 – svick
賓果!非常感謝。 –
我建議你看看這個問題,我問前幾天,結束行動回答我,基本上我一直在尋找一個並行和異步的ForEach方法。
該方法使用SemaphoreSlim
來並行處理事物,它接受異步方法作爲輸入操作。
您可能還想看看我在答覆結束時提供的兩個鏈接,它們對於實現此類行爲非常有幫助,而且它們還包含使用Partitioner
代替的另一種方法。
就我個人而言,我不喜歡Parallel.For
,因爲它是一個同步調用,如我在給出的鏈接中所解釋的;我想這一切「異步」 :-)
+1,除了'SemaphoreSlim'顯然不是必需的OP的情況。我也可以建議在代碼中使用具有超時的'CancellationTokenSource'而不是'Timer'對象。 – Noseratio
調用裏面Parallel.For
您的異步方法最簡單的方法是下一個:
Parallel.For(0, elevations.Count(), async i =>
{
allSheets.AddRange(await BuildSheetsAsync(userID, elevations[i], includeLabels));
});
==============
MarioDS提到的評論絕對正確的,在這種情況下你可能有沒有觀察到的例外。這絕對是非常重要的事情,您應該始終考慮與異步代表達成協議。
在這種情況下,如果您認爲您會有例外情況,則可以在代表內使用try/catch
塊。或者在某些情況下,如果您的情況良好,您可以訂閱TaskScheduler.UnobservedTaskException活動。
這會導致錯誤。異步委託返回「Task」,而Parallel構造不會等待該任務。這意味着異常是不可見的,你不能確定在「並行」之後。因爲調用已經證明所有的工作都已經完成了(你也不能輕易驗證)。 – MarioDS
[Parallel.ForEach中嵌套等待]的可能的重複(https://stackoverflow.com/questions/11564506/nesting-await-in-parallel-foreach) –