2016-05-21 3 views
3

Следующая программа разработана с использованием общей Task.Run() и использует async и ждет (асинхронно). В обоих случаях другой поток берется из пула потоков для новой задачи. Итак, в чем разница? Асинхронный означает, что он должен использовать основной поток и освобождать его до завершения задачи. Но он также использует другой поток, а не использует основной поток.В чем разница между Task.Run() и ожиданием Task.Run()?

public class Worker2 
{ 
    public bool IsComplete { get; private set; } 
    internal void DoWork() 
    { 
     this.IsComplete = false; 
     Console.WriteLine("Doing Work."); 
     Task.Run(new Action(LongOperation)); 
     Console.WriteLine("Work Completed"); 
     IsComplete = true; 
    } 

    private void LongOperation() 
    { 
      Console.WriteLine("long operation thread thread :" + Thread.CurrentThread.ManagedThreadId);//Thread Id = 7. it is different from main thread id. 
      Console.WriteLine("Working!"); 
      Thread.Sleep(3000); 
    } 
} 

// И асинхронные

public class Worker2 
{ 
    public bool IsComplete { get; private set; } 
    internal async void DoWork() 
    { 
     this.IsComplete = false; 
     Console.WriteLine("Doing Work.");  
     await LongOperation(); 
     Console.WriteLine("Work Completed"); 
     IsComplete = true; 
    } 

    private Task LongOperation() 
    { 

     return Task.Run(() => 
      { 
       Console.WriteLine("long operation thread thread :" + Thread.CurrentThread.ManagedThreadId); 
       Console.WriteLine("Working!"); 
       Thread.Sleep(3000); 
      }); 
    } 
} 
+1

Пожалуйста, уделите немного времени, чтобы отформатировать свой код - отступом все надлежащим образом, заблокировать его цитатой на 4 символа, чтобы он * все * отображался как код и удалял пустую строку между каждой полезной строкой. –

+0

Обратите внимание, что в первом примере вы получаете надпись «Work Complete» перед ее завершением. –

+0

Я спрашиваю о том, как потоки используются из пула потоков в обоих случаях. – user3783446

ответ

9

В чем разница между Task.Run() и ожиданием Task.Run()?

Первый запускает задачу и выполняет работу сразу после выполнения этой задачи, до завершения задачи.

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

Проведем аналогию. Ваша первая программа похожа на это:

  • Наймите кого-нибудь, чтобы косить газон.
  • Сообщите своему супругу, что газон косил.
  • Смотреть смотреть Netflix.

Ваша вторая программа:

  • Нанять кого косить газон.
  • Часы Netflix в то время как лужайка косит.
  • Когда лужайка делается скошенной, и фильм закончился, сообщите супругу, что лужайка скошена.

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

+0

2-я программа больше подходит для вашей первой аналогии. Первая программа больше похожа на то, чтобы нанять кого-то, чтобы косить газон и смотреть netflix, но вы говорите своему супругу, что это делается, даже несмотря на то, что парень все еще курит. – Batavia

+0

@ Батавия: Вот что я сказал. –

+0

Хм, мог бы поклясться, что ты их перевернул. my bad – Batavia

4

Вы поняли, что асинхронный код означает. Всякий раз, когда вы вызываете любую функцию, которая передает (делегатам) фактическое выполнение кода для какой-либо другой сущности (другой выделенный поток, пул потоков и т. Д.), И функция немедленно возвращает ваш асинхронный вызов. Асинхронный вызов является антиподом для блокирующего вызова.

В C# есть несколько методов для написания асинхронного кода, а await/async просто упростите запись. Это не добавляет ничего функционального в язык. Это просто синтаксический сахар, чтобы сделать программы более удобными для записи, предоставляя способ писать асинхронный код в том же стиле, который мы пишем блок-код.

Это, как говорится, Task.Run(new Action(LongOperation)); - это асинхронный вызов, а также LongOperation() из вашего второго фрагмента. Разница между ними заключается в том, что в первом примере, когда Task.Run возвращает код, который сразу же следует за тем, что строка выполняется немедленно (при условии, что нисходящий переключатель не произошел). И во втором примере строки, которые следуют за await, выполняются только тогда, когда LongOperation выполнен в некотором потоке, предоставленном пулом потоков (DoWork сразу же возвращается, когда он встречает await).

Я рекомендую вам узнать больше о TPL и async/await. Есть много сообщений в блоге о том, что касается обоих, не говоря уже о больших книгах, охватывающих все эти функции в деталях.