Научно-образовательный IT-форум при КНИТУ-КАИ

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.



[+] Задачи и отмена в .Net

Сообщений 1 страница 6 из 6

1

РЕШЕНИЕ: http://landwatersun.ru/viewtopic.php?id=444#p1619

Демонстрируется пример программы, в котором создается и отменяется задача.

Код:
using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        // Метод выполняемый в качестве задачи
        static void MyTask(Object ct)
        {
            CancellationToken cancelTok = (CancellationToken)ct;
            cancelTok.ThrowIfCancellationRequested();

            Console.WriteLine("MyTask() №{0} запущен", Task.CurrentId);

            for (int count = 0; count < 10; count++)
            {
                // Используем опрос
                if (!cancelTok.IsCancellationRequested)
                {
                    Thread.Sleep(500);
                    Console.WriteLine("В методе MyTask №{0} подсчет равен {1}", Task.CurrentId, count);
                }
            }

            Console.WriteLine("MyTask() #{0} завершен", Task.CurrentId);

            cancelTok.ThrowIfCancellationRequested();
        }

        static void Main()
        {
            Console.WriteLine("Основной поток запущен");

            // Объект источника признаков отмены
            CancellationTokenSource cancelTokSSrc = new CancellationTokenSource();

            // Запустить задачу, передав ей признак отмены
            Task tsk = Task.Factory.StartNew(MyTask, cancelTokSSrc.Token);

            Thread.Sleep(2000);
            try
            {
                // отменить задачу
                cancelTokSSrc.Cancel();
                tsk.Wait();
            }
            catch (AggregateException exc)
            {              
               if (exc.InnerException is OperationCanceledException)
                    Console.WriteLine("Задача tsk отменена");
            }
            finally
            {
                tsk.Dispose();
                cancelTokSSrc.Dispose();
            }

            Console.WriteLine("Основной поток завершен");
            Console.ReadLine();
        }
    }
}

ВОПРОС:
Почему, если в программе строку:
if (exc.InnerException is OperationCanceledException)
заменить на:
if (tsk.IsCanceled),
то в условии будет значение false и сообщение об отмене задачи не будет?

2

В качестве источника для изучения советую почитать http://habrahabr.ru/post/168669/

3

Попытка №1.
Исходя из хабра, что CanBeCanceled равно false, то tsk.IsCanceled будет также равно false, раз запроса на отмену нет, то и сообщение выводится не должно. + нет исключения OperationCanceledException.

Отредактировано STV (2015-11-13 15:52:50)

4

Все просто:

Код:
Task.Factory.StartNew(MyTask, cancelTokSSrc.Token);

заменяем на

Код:
Task.Factory.StartNew(MyTask, cancelTokSSrc.Token, cancelTokSSrc.Token);

Т.е. используем конструктор:

Код:
StartNew(Action<Object>, Object, CancellationToken)

На хабре также токен передается и в такс и в метод:

Код:
var task = Task.Run(() => SomeWork(cts.Token), cts.Token);

Чтобы сработал IsCancelled=true необходимо передать токен конструктор таска https://msdn.microsoft.com/en-us/library/dd997396(VS.100).aspx

Отредактировано rozh (2015-11-13 16:04:15)

5

STV написал(а):

Попытка №1.
Исходя из хабра, что CanBeCanceled равно false, то tsk.IsCanceled будет также равно false, раз запроса на отмену нет, то и сообщение выводится не должно. + нет исключения OperationCanceledException.

Отредактировано STV (Сегодня 15:52:50)

Да, но в программе имеется запрос на отмену:

Код:
cancelTokSSrc.Cancel();

6

rozh написал(а):

Чтобы сработал IsCancelled=true необходимо передать токен конструктор таска https://msdn.microsoft.com/en-us/library/dd997396(VS.100).aspx

Верно, Роман. Молодец! :)
Спасибо, Роман, что уделил внимание и полно ответил на вопрос.