2016-09-26 8 views
0

Для примера рассмотрим:Должен ли я когда-либо нуждаться в задачах `await` для шаблона посетителя?

public class Student 
{ 
    public async Task Run() 
    { 
     var rand = new Random(); 
     while (true) 
     { 

      await ReadBook(); 
      await Task.Delay(rand.Next(4000)); 
     } 
    } 

    public async Task ReadBook() 
    { 
     // ... 
    } 
} 

class Main 
{ 
    async Task Run() 
    { 
     var s1 = new Student(); 
     var s2 = new Student(); 

     s1.Run(); 
     s2.Run(); 

     while (true) 
     { 
      Console.WriteLine("Books read: {0}", GetReadBooks()); 
      await Task.Delay(10000); 
     } 
    } 

    int GetReadBooks() 
    { 
     return 1; 
    } 
} 

Нужно ли мне ждать Student.Run(), или даже сохранить ссылку на возвращаемом задачи на всех? Я понимаю необходимость, если я когда-либо захочу отменить задачу; Я подозреваю, что мне также нужно дождаться этого, чтобы получить какие-либо исключения, брошенные Student.Run(), но кроме того, мне все равно, чем эти задачи?

+1

Вы никогда не должны оставлять свои исключения незаметными. То, что обработка исключений, должна быть достаточной причиной, чтобы оставаться с 'await' даже без каких-либо других причин. – hvd

+0

Рассмотрите это скорее из академического вопроса; Я ожидаю, что в конечном итоге буду ждать и исключения. – Rollie

+0

В этом вопросе нет шаблона посетителя. Пожалуйста, измените заголовок и удалите тег. – Euphoric

ответ

0

Можно ли двум студентам читать книги одновременно?

Оставив await будет означать, что s2.Run() начинается, когда s1.Run() находится в процессе. В этом случае вы хотитеs1.Run() и s2.Run() для запуска одновременно, поэтому вам определенно не следует просто писать await s1.Run();. Поскольку ваши циклы никогда не заканчиваются, ожидание их не имеет особого смысла, кроме исключений, но я был бы удивлен, если ваши петли действительно никогда не заканчиваются в вашем реальном коде. Task предназначен для представления чего-то, что заканчивается в какой-то момент. И если вы можете сказать, когда это закончится, тогда вы можете определить на основе того, что подходит для await.

Я бы предположил, что сохранение заданий в переменных и размещение await Task.WhenAll(run1, run2); где-то после, было бы наиболее подходящим, но в зависимости от вашего реального кода это может быть не подходит для вас.

+0

Там * есть * ожидание внутри 'Student.Run()' при вызове 'ReadBook()'. Отсутствует ожидание при вызове 'Student.Run()'. Нет, студент не может читать 2 книги в одно и то же время, но 2 ученика * могут * читать одну и ту же книгу одновременно. – Rollie

+0

Это не так, как 'await' будет работать правильно? К моменту истечения потока 'await', он будет ожидать завершения этой строки кода. Таким образом, приведенный выше код выполняет синхронный – Bharadwaj

+0

@ Rollie Ах, извините, неправильно прочитайте эту часть. То, что я попытался сделать, все же применяется, но для «Run()» есть еще что-то для этого. – hvd