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

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

<b>    // Проверить, отменена ли задача,</b>

<b>    // прежде чем запускать ее.</b>

<b>    cancelTok.ThrowIfCancellationRequested();</b>

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

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

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

<b>      if(cancelTok.IsCancellationRequested) {</b>

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

<b>        cancelTok.ThrowIfCancellationRequested();</b>

<b>      }</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>  static void Main() {</b>

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

<b>    // Создать объект источника признаков отмены.</b>

<b>    CancellationTokenSource cancelTokSrc = new CancellationTokenSource();</b>

<b>    // Запустить задачу, передав признак отмены ей самой и делегату.</b>

<b>    Task tsk = Task.Factory.StartNew(MyTask, cancelTokSrc.Token,</b>

<b>              cancelTokSrc.Token);</b>

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

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

<b>    try {</b>

<b>      // Отменить задачу.</b>

<b>      cancelTokSrc.Cancel();</b>

<b>      // Приостановить выполнение метода Main() до тех пор,</b>

<b>      // пока не завершится задача tsk.</b>

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

<b>    } catch (AggregateException exc) {</b>

<b>      if(tsk.IsCanceled)</b>

<b>        Console.WriteLine(&quot;nЗадача tsk отменена&quot;);</b>

<b>      // Для просмотра исключения снять комментарии со следующей строки кода:</b>

<b>      // Console.WriteLine(exc);</b>

<b>    } finally {</b>

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

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

<b>    }</b>

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

<b>  }</b>

<b>}</b>

Ниже приведен результат выполнения этой программы. Обратите внимание на то что задача отменяется через 2 секунды.

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

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

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

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

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

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

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

<b>Задача tsk отменена</b>

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

Как следует из приведенного выше результата, выполнение метода MyTask() отменяется в методе Main() лишь две секунды спустя. Следовательно, в методе MyTask() выполняются четыре шага цикла. Когда же перехватывается исключение AggregateException, проверяется состояние задачи. Если задача tsk отменена, что и должно произойти в данном примере, то об этом выводится соответствующее сообщение. Следует, однако, иметь в виду, что когда сообщение AggregateException генерируется в ответ на отмену задачи, то это еще не свидетельствует об ошибке, а просто означает, что задача была отменена.

Выше были изложены лишь самые основные принципы, положенные в основу отмены задачи и генерирования исключения AggregateException. Тем не менее эта тема намного обширнее и требует от вас самостоятельного и углубленного изучения, если вы действительно хотите создавать высокопроизводительные, масштабируемые приложения.

Другие средства организации задач

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

В предыдущем разделе было дано краткое описание исключения AggregateException, но у него имеются также другие особенности, которые могут оказаться весьма полезными. К их числу относится метод Flatten(), применяемый для преобразования любых внутренних исключений типа AggregateException в единственное исключение AggregateException. Другой метод, Handle(), служит для обработки исключения, составляющего совокупное исключение AggregateException.