2013-09-22 2 views
0

Недавно я столкнулся с некоторым асинхронным кодом с асинхронным ожиданием. Мой вопрос заключается в чем разница между двумя блоками кода ниже -Вызов с двумя асинхронными вызовами

Код блока - 1

public async Task Method1(string fileName) 
{ 
    await Method2(fileName); 
} 

public async Task Method2(string filePath) 
{ 
    await Task.Run(() =>{ 
     //do some task 
    }); 
} 

Блок кода - 2

public async Task Method1(string fileName) 
{ 
    await Method2(fileName); 
} 

public async Task Method2(string filePath) 
{ 
    Task.Run(() =>{ 
     //do some task 
    }); 
} 

Разница между этими двумя кодами ожидаем по методу2. Что происходит, когда третий метод (например, метод3) вызывает метод 1? Каковы различия в исполнении, наблюдаемые в методе 3?

+1

Код №2 должен дать вам предупреждение, объясняющее, в чем разница. Не игнорируйте предупреждения от компилятора. – svick

+0

@svick Спасибо. Компилятор говорит, что метод не имеет ожидающего оператора и будет работать синхронно. Теперь подумайте о методе3, о котором я упомянул. Когда метод3 вызывает метод 1, управление возвращается в метод3 после достижения ожидающего вызова в обоих случаях. Итак, какая разница? – Muctadir

+0

Разница заключается в том, когда завершена 'Task', возвращаемая из' Method1'. С # 2 он будет завершен немедленно (не дожидаясь завершения 'Task' в' Task.Run() '). – svick

ответ

3

Там серьезная проблема с Method2:

public async Task Method2(string filePath) 
{ 
    Task.Run(() =>{ 
     //do some task 
    }); 
} 

Он работает синхронно и возвращает Task объект, который является полным (Task.IsComplete == true). Прежде чем он вернется, он запустит еще одну задачу (с Task.Run), которая выполняется асинхронно и результат завершения завершается («огонь и забыть»). Было бы более целесообразно сформулировать это следующим образом:

public Task Method2(string filePath) 
{ 
    return Task.Run(() =>{ 
     //do some task 
    }); 
} 
2

Во втором кодовом блоке Method2 завершится, не дожидаясь завершения Task.Run в пределах Method2.

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

+0

Извините, я не мог понять ясно. можете ли вы объяснить подробно? – Muctadir

+0

В блоке 2 кода Method2 запускает задачу. Допустим, что для выполнения этих задач требуется 10 секунд. Метод2 фактически завершится до завершения задачи. Это означает, что вы можете запустить Method2 без ожидания 10 секунд для завершения и сделать что-то еще в то же время ... пить кофе или что не – MichaC

+0

Спасибо. Но разве это не то же самое в случае блока кода1? – Muctadir

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