2014-04-09 41 views
0

可以說我有一個需要異步處理的對象集合。對asyc執行的限制

List<Customer> customers = GetAllCustomers(); 

customers.ForEach(async (e) => { await e.Process(); }); 

我認爲這些將被異步處理,而不保留當前線程。我想知道的是,如果有多少客戶可以在集合中有限制。如果它是100,000,它會在異步隊列中排隊嗎?

**我也不確定這是否正確。我並不需要等待每個客戶處理的結果。我只想爲所有人無縫處理客戶數據。我不在乎每個過程是否失敗,因爲它會再次被拿起,直到成功。我可以使用任務,但我寧可不創建線程從而可能導致比賽條件等**

+0

你知道是什麼任務呢? – ilansch

+0

你正在向'Parallel.ForEach'傳遞'async void'lambda'Action'。您應該意識到,執行控制一旦在lambda內部遇到'await',就會立即返回到'Parallel.ForEach',然後它基本上是'Parallel.ForEach'之外的一個繼續調用的調用。可能不是你在找什麼? – Noseratio

+0

只要它擊中每條記錄異步,它應該沒問題。該方法是自給自足的,如果失敗,它將被拿起來再次處理。 –

回答

4

我想知道的是,如果有多少客戶可以在收集限制。如果它是100,000,它會在異步隊列中排隊嗎?

沒有限制。但是,每次處理是一次啓動;也就是說,Process方法(我假設它是異步的,應該叫做ProcessAsync)將被調用一次,每個項目返回一個Task<T>

如果你想(異步)等待所有的任務來完成,你可以使用Task.WhenAll這樣:

await Task.WhenAll(customers.Select(e => e.Process())); 
+0

您提到Process方法應該被稱爲ProcessAsync。你是什​​麼意思?這是一種自定義的方法。它可以被命名爲ProcessCustomer。 –

+3

@AlexJ [基於任務的異步模式(TAP)](http://msdn.microsoft.com/zh-cn/library/hh873175)表示,所有異步方法的名稱末尾應該有'Async'。這是爲了清楚哪些方法是異步的(並且必須「等待」)。 – svick

+0

好的,謝謝你的解釋。 ProcessAsyc方法是否也需要定義中的異步?如在公共靜態異步任務ProcessAsync(),或裝飾不是必需的? –

0

Tasks更適合於這種類型的負載,可以設置選項來控制多少線程等。

List<Task> tasks = new List<Task>(); 
customers.ForEach((e) => { Task task = Task.Run(() =>{ e.Process(); tasks.Add(task);})}); 

Task.WaitAll(tasks.ToArray()); 
+0

任務不是異步的。 http://stackoverflow.com/questions/9519414/whats-the-difference-between-task-start-wait-and-async-await –

+0

任務運行在自己的線程,所以是的,他們是異步的。 –

+0

Task.WaitAll(tasks.ToArray());將保持當前線程直到完成,如果我沒有錯。 –