Добавить в цитаты Настройки чтения

Страница 425 из 502

<b>    tsk2.Start();</b>

<b>    Console.WriteLine(&quot;Идентификатор задачи tsk: &quot; + tsk.Id);</b>

<b>    Console.WriteLine(&quot;Идентификатор задачи tsk2: &quot; + tsk2.Id);</b>

<b>    // Сохранить метод Main() активным до завершения остальных задач,</b>

<b>    for(int i = 0; i &lt; 60; i++) {</b>

<b>      Console.Write(&quot;.&quot;);</b>

<b>      Thread.Sleep (100);</b>

<b>    }</b>

<b>    Console.WriteLine(&quot;Основной поток завершен.&quot;);</b>

<b>  }</b>

<b>}</b>

Выполнение этой программы приводит к следующему результату.

<b>Основной поток запущен.</b>

<b>Идентификатор задачи tsk: 1</b>

<b>Идентификатор задачи tsk2: 2</b>

<b>.MyTask() №1 запущен</b>

<b>MyTask() №2 запущен</b>

<b>....В методе MyTask() #1, подсчет равен 0</b>

<b>В методе MyTask() #2, подсчет равен 0</b>

<b>.....В методе MyTask() #1, подсчет равен 1</b>

<b>В методе MyTask() #2, подсчет равен 1</b>

<b>.....В методе MyTask() #1, подсчет равен 2</b>

<b>В методе MyTask() #2, подсчет равен 2</b>

<b>....В методе MyTask() #2, подсчет равен 3</b>

<b>В методе MyTask() #1, подсчет равен 3</b>

<b>.....В методе MyTask() #1, подсчет равен 4</b>

<b>В методе MyTask() #2, подсчет равен 4</b>

<b>.....В методе MyTask() #1, подсчет равен 5</b>

<b>В методе MyTask() #2, подсчет равен 5</b>

<b>.....В методе MyTask() #1, подсчет равен 6</b>

<b>В методе MyTask() #2, подсчет равен 6</b>

<b>....В методе MyTask() #1, подсчет равен 7</b>

<b>В методе MyTask() #2, подсчет равен 7</b>

<b>.....В методе MyTask() #1, подсчет равен 8</b>

<b>В методе MyTask() #2, подсчет равен 8</b>

<b>.....В методе MyTask() #2, подсчет равен 9</b>

<b>MyTask №2 завершен</b>

<b>В методе MyTask() #1, подсчет равен 9</b>

<b>MyTask №1 завершен</b>

<b>............Основной поток завершен.</b>

Применение методов ожидания

В приведенных выше примерах основной поток исполнения, а по существу, метод Main(), завершался потому, что такой результат гарантировали вызовы метода Thread.Sleep(). Но подобный подход нельзя считать удовлетворительным.

Организовать ожидание завершения задач можно и более совершенным способом, применяя методы ожидания, специально предоставляемые в классе Task. Самым простым из них считается метод Wait(), приостанавливающий исполнение вызывающего потока до тех пор, пока не завершится вызываемая задача. Ниже приведена простейшая форма объявления этого метода.

<b>public void Wait()</b>

При выполнении этого метода могут быть сгенерированы два исключения. Первым из них является исключение ObjectDisposedException. Оно генерируется в том случае, если задача освобождена посредством вызова метода Dispose(). А второе исключение, AggregateException, генерируется в том случае, если задача сама генерирует исключение или же отменяется. Как правило, отслеживается и обрабатывается именно это исключение. В связи с тем что задача может сгенерировать не одно исключение, если, например, у нее имеются порожденные задачи, все подобные исключения собираются в единое исключение типа AggregateException. Для того чтобы выяснить, что же произошло на самом деле, достаточно проанализировать внутренние исключения, связанные с этим совокупным исключением. А до тех пор в приведенных далее примерах любые исключения, генерируемые задачами, будут обрабатываться во время выполнения.

Ниже приведен вариант предыдущей программы, измененный с целью продемонстрировать применение метода Wait() на практике. Этот метод используется внутри метода Main(), чтобы приостановить его выполнение до тех пор, пока не завершатся обе задачи tsk и tsk2.

<b>// Применить метод Wait().</b>

<b>using System;</b>

<b>using System.Threading;</b>

<b>using System.Threading.Tasks;</b>

<b>class DemoTask {</b>

<b>  // Метод, исполняемый как задача,</b>

<b>  static void MyTask() {</b>

<b>    Console.WriteLine(&quot;MyTask() №&quot; + Task.CurrentId + &quot; запущен&quot;);</b>

<b>    for(int count = 0; count &lt; 10; count++) {</b>

<b>      Thread.Sleep(500);</b>

<b>      Console.WriteLine(&quot;В методе MyTask() #&quot; + Task.CurrentId +</b>

<b>             &quot;, подсчет равен &quot; + count );</b>

<b>    }</b>