2013-11-14 2 views
0

Я научился использовать Task легко чем async/await. Теперь я пытаюсь использовать Task, чтобы узнать async/await.async/wait и Task/Wait in C# то же самое?

static void Main(string[] args) 
    { 
     Console.ReadKey(true); 
     //Magic1(); 
     Magic2(); 
     Console.WriteLine("{0}", DateTime.Now.ToString()); 
     Console.ReadKey(true); 
    } 

    static async void Magic1() 
    { 
     var taskA = GetDataAsync(); 
     var taskB = GetDataAsync(); 
     var taskC = GetDataAsync(); 

     Console.WriteLine("a: " + await taskA); 
     Console.WriteLine("b: " + await taskB); 
     Console.WriteLine("c: " + await taskC); 
    } 

    static Task Magic2() 
    { 
     return Task.Run(() => 
     { 
      var taskA = GetDataAsync(); 
      var taskB = GetDataAsync(); 
      var taskC = GetDataAsync(); 

      Task.WaitAll(new Task[] { taskA, taskB, taskC }); 

      Console.WriteLine("a: " + taskA.Result); 
      Console.WriteLine("b: " + taskB.Result); 
      Console.WriteLine("c: " + taskC.Result); 
     }); 
    } 

    static Task<string> GetDataAsync() 
    { 
     return Task.Run(() => 
     { 
      var startTime = DateTime.Now; 
      for (var i = 0; i < 1000000000; i++) 
      { 
      } 
      var endTime = DateTime.Now; 
      return startTime.ToString() + " to " + endTime.ToString() + " is " + (endTime - startTime).ToString(); 
     }); 
    } 

Я создал два метода, которые, как представляется, сделать то же самое, мои вопросы:

1) является Magic1 и Magic2 же под капотом?

2) Если они не совпадают, могу ли я преобразовать Magic1 в метод, который делает то же самое, не используя async и await ключевых слов?

+0

Я не совсем уверен, что вы подразумеваете под «можно преобразовать Magic1» в метод, который использует «Задача». Можете ли вы подробно остановиться на этом? –

+0

Извините, я имею в виду без использования async и ожидания ключевых слов, возможно ли это для меня чтобы написать тот же метод, который делает то же самое? – dpp

+0

ah Я вижу, обновил свой ответ –

ответ

4

Теперь я пытаюсь использовать свои знания в задаче научиться асинхронной/Await.

Я действительно рекомендую вам не сделать это. Хотя параллелизм на основе задач (.NET 4.0) и асинхронный шаблон на основе задач (async/await) используют один и тот же тип (Task), они совершенно разные. Они решают разные проблемы и имеют другой способ работы.

Вместо этого предлагаю вам притвориться, что вы ничего не знаете о типе Task и начинаете с моего async intro. В конце моего ввода async вводятся несколько дополнительных ресурсов, включая документы MSDN, которые неплохо подходят для этой функции.

Если вы действительно знакомы с продолжениями, вы можете (в основном) думать о await как означающее «переписать остальную часть этого метода, как продолжение и график его с помощью тока SynchronizationContext или TaskScheduler». Но даже это только приближение; есть много крайних случаев. Это совсем не то же самое, что делать Task.Wait[All] в пределах Task.Run.

+0

Я действительно читал ваш блог, прежде чем задал свой вопрос. :) Я прочитаю его еще раз. – dpp

1

Различия между этими двумя методами:

  • Где их код работает. Magic2 будет работать в threadpool, а не в контексте синхронизации вызывающего, потому что вы (без необходимости) использовали Task.Run. Если вы пишете код пользовательского интерфейса, это может привести к сбою Magic2.
  • Блокировка. Magic1 блокирует вызывающего абонента до его завершения. Обычно это ошибка при написании асинхронного кода. Magic2 не будет блокировать вызывающего абонента, даже если вы удалите Task.Run.
  • Инкрементные работы. Если taskB занимает значительно больше времени для завершения, это не задержит Magic2 от печати результата taskA. Magic1 ждет завершения всех трех задач, поэтому он не будет печатать taskA до завершения задания B.
+0

Когда вы говорите: «Magic1 блокирует вызывающего абонента до его завершения», вы имеете в виду, что метод 'Main' не будет выполнять никакого кода до' Magic1 'сделано? – dpp

+0

Это именно то, что он имеет в виду.Чтобы он не блокировался, верните «Задачу». Возможно, используйте 'Task.WhenAll'. –

+0

'Magic2' возвращает' Task' уже ... – dpp

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