2016-02-17 2 views
1

У меня есть следующий код:Ждут конец Parallel.Invoke() в C#

Parallel.Invoke(
       () => this.GetUsers(), 
       () => this.GetFrequentVisitors(), 
       () => this.GetTenantSettings(), 
       () => this.GetTranslations() 
      ); 

Все эти Async Task методы, они все вместе занимают около 30 сек, а параллельно должен принять около 7.

Прямо сейчас, если я регистрирую время до и после Parallel.Invoke, у меня есть меньше секунды.

Мои вопросы: Почему? И как мне await.Invoke(), поэтому я знаю, когда закончится последний из звонков?

Сейчас я могу достичь только того, что кажется либо мгновенным, что кажется неправильным, либо все в последовательности, что невыносимо для пользователя.

Я также попытался это:

Task users = this.GetUsers(); 
    Task visitors = this.GetFrequentVisitors(); 
    Task settings = this.GetTenantSettings(); 
    Task translations = this.GetTranslations(); 


    Task.WaitAll(users, visitors, settings, translations); 

который, кажется, просто повесить там навсегда и блокирует мое приложение.

Примечание: это метод async Task, который я ожидаю, но внутри нет ожиданий (то, что я показал, является полным методом). Если я его изменю, я не получаю никакого другого результата.

Может ли кто-нибудь помочь мне немного? С небольшим объяснением? Сейчас я борюсь с асинхронным потоком.

Чтение этого article помогло немного, но им, похоже, не нужно await.Invoke(), что меня удивляет.

+0

Если все методы, о которых вы упомянули, являются асинхронными, то почему бы не просто сделать что-то вроде 'wait GetUsers(); ждать GetFrequentVisitors(); 'и так далее? –

+1

Блоки «Parellel.Invoke». Вы не можете (не можете) ждать. Фактически, он использует текущий поток для выполнения одного из методов. Что делают методы? Почему вы думаете, что что-то не так? Если методы на самом деле асинхронны, вам нужны 'Task.WaitAll' или' Task.WhenAll', а не Parallel.Invoke –

+0

@AndyKorneyev, которые будут выполнять методы последовательно, а не параллельно. –

ответ

4

С вашим вариантом WaitAll «висит навсегда», это говорит о том, что вы находитесь, скажем, в потоке пользовательского интерфейса, и один или несколько из этих методов также хотят попасть в поток пользовательского интерфейса.

Изменить этот текущий метод, чтобы быть async, так что вы можете вместо await:

Task users = this.GetUsers(); 
Task visitors = this.GetFrequentVisitors(); 
Task settings = this.GetTenantSettings(); 
Task translations = this.GetTranslations(); 

await Task.WhenAll(users, visitors, settings, translations); 

И, главное, это теперь будет высвободить поток пользовательского интерфейса (или другой важный контекст синхронизации) так, что эти другие асинхронные методы может добиться прогресса.

+0

Позвольте мне попробовать это, WhenAll выглядит многообещающим, не знал, что он существует: l –

+1

Ну, это работает просто отлично. Спасибо всем за помощь, поэтому мне нравится это сообщество. Глядя на ваши комментарии и документацию, теперь все ясно и на самом деле довольно очевидно. –

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