2015-11-20 4 views
3

У меня есть некоторые недоразумения с C# async/ждут механизм. Есть ли существенная разница междуКогда несколько ожиданий имеют смысл?

private async void Init() 
{ 
    await Task.Run(() => Do1()); 
    await Task.Run(() => Do2()); 
} 

и

private async void Init() 
{ 
    await Task.Run(() => 
    { 
     Do1(); 
     Do2(); 
    }); 
} 

Единственное различие, которое я вижу: в первом образце Do1 и dO2 будут работать в разных потоках, а во втором образце - в том же нить. Но опять же, какова реальная польза от него, и когда я должен предпочесть первый подход к второму и наоборот?


EDIT: Второй случай

В чем разница между

private async void Init() 
{ 
    await Task.Run(() => Do1()); 
    Do3(); 
} 

и

private async void Init() 
{ 
    await Task.Run(() => 
    { 
     Do1(); 
     Do3(); 
    }); 
} 
+0

В вашем конкретном случае второй подход лучше. Поскольку любой способ после Do1, Do2 будет выполнен без каких-либо различий в результатах. task.run добавляет некоторые накладные расходы при первом подходе. Также обратите внимание, что в обоих случаях Do1 запускается первым, и после того, как он заканчивается, Do2 запускает –

+0

@ M.kazemAkhgary в первой ситуации, они запускаются один за другим, когда задача запускается, и мы сразу же ждем? т.е. будут ли они оба работать одновременно, если они были назначены переменной и начались как до первого? – Dhunt

+0

Да. Если вы храните их в переменной, а затем ожидаете, что они будут запускаться индивидуально, но теперь, потому что есть ожидание сразу после создания задач, они запускаются один за другим. @Dhunt –

ответ

3

Разница заключается в том:

Первый пример:

  • Вы очереди Do1 на Threadpool нити и асинхронно ждать его завершения, затем выполните то же самое с Do2. Они могут работать на разных потоках.
  • Вы ставите Do1 и Do2, чтобы выполнить синхронно один за другим в одном потоке потока потока.

Второй пример:

  • Очередь Do1 на ThreadPool и асинхронно ждать его завершения, а затем вызвать Do3 синхронно.
  • Это точно так же, как и вторая часть первого примера.

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

Я предполагаю, что вы спрашиваете себя, предпочтительнее ли другой, и как в большинстве случаев это зависит. Если вы используете внутри консольного приложения, и вы собираетесь асинхронно ждать завершения Do1, то передайте оба метода тому же вызову Task.Run. Если вы планируете делать это в том месте, где важна синхронизация, например, в графическом приложении, тогда в поток пользовательского интерфейса должна быть активирована любая операция, которая должна взаимодействовать с элементами управления пользовательским интерфейсом.

Другой вариант, который чаще встречается, заключается в том, что у вас есть две операции, которые независимы друг от друга, и вы хотите начать их вместе и дождаться завершения. Это где вы будете использовать Task.WhenAll:

var firstDo = Task.Run(() => Do1()); 
var secondDo = Task.Run(() => Do2()); 
await Task.WhenAll(firstDo, secondDo); 

примечание стороны:

Не использовать async void в асинхронных методов без возвращаемого значения, то есть то, что async Task для. Первый предназначен только для обеспечения совместимости с обработчиками событий, где я предполагаю, что это не так.

0
  • если Do1() и Do2() независимы друг от друга, вы должны запустить их в отдельности. Это еще более важно, если они являются длительными/блокирующими процессами
  • , с другой стороны, если они связаны друг с другом, и первый выполняет некоторые операции, которые требуются другим, тогда лучше запустить их в одном потоке для уменьшения накладных расходов. В конце концов, вы заранее знаете, что они должны выполняться последовательно
+0

В обоих случаях они запускают один и тот же другой. Единственное различие, которое я вижу: в первом случае они будут запускаться каждый в своей собственной нити. Но не одновременно! Тема второй задачи будет запущена только после завершения первой задачи. Поэтому я не вижу существенной разницы между случаями, кроме некоторых служебных накладных расходов. – Sergey

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