2014-06-28 5 views
2

У меня есть следующий простой вопрос: почему метод async не ждет завершения параллельного цикла?Параллельный метод и асинхронный метод

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

Есть ли какой-нибудь метод 'awaitable' внутри цикла' Parallel.For'? – GeorgeChond

ответ

-1

С Parallel.For идеально выполняет несколько задач параллельно, было бы бессмысленно ждать отдельных задач, поскольку это по сути делало бы сериализацию их выполнения. Почему ParallelLoopResult не является подклассом Задачи, хотя для меня это загадка. В то время как вы могли бы сделать что-то вроде

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

он не будет покупать вам ничего, так как вы уже в методе асинхронным и будет ли ваш поток или один созданный Task.Run является один сидит вокруг блокировки для Parallel.For не имеет никакого значения в этой точке.

Лучшее, что я могу представить, это то, что ParallelLoopResult был написан таким образом, что ему нужна нить, чтобы сидеть, чтобы собрать состояние цикла.

+0

«он тебя ничего не купит». – usr

1

Просто используйте его без «async»: это будет самый простой способ обеспечить завершение процедуры, все еще находящейся в параллельном режиме выполнения, до перехода на следующую строку (другими словами, он блокирует основной пользовательский интерфейс, ожидающий завершение рабочего процесса, который сам по себе работает некоторый материал в параллельном режиме):

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

Кроме того, вы можете посмотреть на примере, приведенный Александр Русин (http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx) с использованием Task.Factory.ContinueWhenAll() применительно к вашей проблеме (в случае работы в режиме Parallel/async). Rgds,

Смежные вопросы