2014-06-28 106 views
2

我有一個簡單的問題 - 爲什麼異步方法不會等待並行循環完成?並行和異步方法

public async Task<List<object>> DoSomeAsync() 
{ 
    // some async actions with streams and web requests 
    // ... 
    ConcurrentQueue<object> queue = new ConcurrentQueue<object>();  

    Parallel.For(1, x, async i => 
    { 
     // a little chunk of code 
     // ... 
     queue.Enqueue(new object()); 
     // ... 
     // a little chunk of code again 
    } 

    return queue.ToList(); // debugger says that this statement is executed earlier than parallel loop. 
} 

你知道我有什麼想法,我該如何等待執行並行循環?

+0

可能您需要'await Parallel.For(...)' – Grundy

+5

並行循環無法等待,因爲它們不返回任務實例。 – vdrake6

+0

Parallel.For'循環裏面有沒有'awaitable'方法? – GeorgeChond

回答

-1

由於Parallel.For理想地並行地執行多個任務,因此等待各個任務是沒有意義的,因爲這會固有地序列化它們的執行。爲什麼ParallelLoopResult不是Task的子類,雖然對我來說是個謎。雖然你可以不喜歡

await Task.Run(() => Parallel.For(...) 

,因爲你已經在異步方法以及是否你的線程或Task.Run創建的是一個坐在那裏阻斷Parallel.For在這一點無關緊要,將購買你什麼。

最好的我能想到的是,ParallelLoopResult是這樣編寫的,它需要一個線程來坐下來收集循環的狀態。

+0

「它不會給你買東西」。 – usr

1

只需使用它而不需要「異步」:它將是一種最簡單的方法,以確保程序的完成,仍處於並行執行模式,然後移動到下一行(換句話說,它阻止主UI等待工作進程,這本身是運行在並行模式下的一些東西)完成:

Parallel.For(1, x, (i) => 
    { 
     // a little chunk of code 
     // ... 
     queue.Enqueue(new object()); 
     // ... 
     // a little chunk of code again 
    }); 

此外,作爲適用於您的問題,您可以看看亞歷山德拉Rusina給出(http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx)使用Task.Factory.ContinueWhenAll()的例子(在並行/異步模式下運行)。 Rgds,