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

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

<b>// Применить лямбда-выражение в качестве задачи.</b>

<b>using System;</b>

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

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

<b>class DemoLambdaTask {</b>

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

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

<b>    // Далее лямбда-выражение используется для определения задачи.</b>

<b>    Task tsk = Task.Factory.StartNew(() =&gt; {</b>

<b>      Console.WriteLine(&quot;Задача запущена&quot;);</b>

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

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

<b>        Console.WriteLine(&quot;Подсчет в задаче равен &quot; + count );</b>

<b>      }</b>

<b>      Console.WriteLine(&quot;Задача завершена&quot;);</b>

<b>    } );</b>

<b>    // Ожидать завершения задачи tsk.</b>

<b>    tsk.Wait();</b>

<b>    // Освободить задачу tsk.</b>

<b>    tsk.Dispose();</b>

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

<b>  }</b>

<b>}</b>

Ниже приведен результат выполнения этой программы.

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

<b>Задача запущена</b>

<b>Подсчет в задаче равен 0</b>

<b>Подсчет в задаче равен 1</b>

<b>Подсчет в задаче равен 2</b>

<b>Подсчет в задаче равен 3</b>

<b>Подсчет в задаче равен 4</b>

<b>Подсчет в задаче равен 5</b>

<b>Подсчет в задаче равен 6</b>

<b>Подсчет в задаче равен 7</b>

<b>Подсчет в задаче равен 8</b>

<b>Подсчет в задаче равен 9</b>

<b>Задача завершена</b>

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

Помимо применения лямбда-выражения для описания задачи, обратите также внимание в данной программе на то, что вызов метода tsk.Dispose() не делается до тех пор, пока не произойдет возврат из метода tsk.Wait(). Как пояснялось в предыдущем разделе, метод Dispose() можно вызывать только по завершении задачи. Для того чтобы убедиться в этом, попробуйте поставить вызов метода tsk.Dispose() в рассматриваемой здесь программе перед вызовом метода tsk.Wait(). Вы сразу же заметите, что это приведет к исключительной ситуации.

Создание продолжения задачи

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

<b>public Task ContinueWith(Action&lt;Task&gt; действие_продолженмя)</b>

где действие_продолжения обозначает задачу, которая будет запущена на исполнение по завершении вызывающей задачи. У делегата Action имеется единственный параметр типа Task. Следовательно, вариант делегата Action, применяемого в данном методе, выглядит следующим образом.

<b>public delegate void Action&lt;in T&gt;(T obj) </b>

В данном случае обобщенный параметр Т обозначает класс Task.

Продолжение задачи демонстрируется на примере следующей программы.

<b>// Продемонстрировать продолжение задачи. </b>

<b>using System; </b>

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

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

<b>class ContinuationDemo { </b>

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

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

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

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

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

<b>      Console.WriteLine(&quot;В методе MyTask() подсчет равен &quot; + count ); </b>

<b>    }</b>

<b>    Console.WriteLine(&quot;MyTask завершен&quot;); </b>

<b>  }</b>

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

<b>  static void ContTask(Task t) { </b>

<b>    Console.WriteLine(&quot;Продолжение запущено&quot;); </b>