Как правильно остановить Task?

308
12 апреля 2017, 11:43
CancellationTokenSource cts = new CancellationTokenSource();
Task th = new Task(OutHookProc.prockill, cts.Token);

Останавливаю так:

cts.Cancel();

Как правильно остановить ?

Answer 1

Вы не можете остановить бегущий таск точно так же, как вы не можете остановить бегущий thread. Вы можете лишь попросить таск остановиться, М надеяться, что он послушает вашу просьбу.

Если метод OutHookProc.prockill под вашим контролем, поменяйте его сигнатуру так, чтобы он принимал ещё и CancellationToken, передавайте токен ещё и туда, и в методе время от времени проверяйте токен и прекращайтесь работу, если токен запрашивает это. Если вы внутри OutHookProc.prockill вызываете другие асинхронные методы, передавайте им токен тоже.

Если метод не под вашим контролем и не предоставляет средств для остановки, остановить его никак нельзя. Единственное, что можно сделать — это проигнорировать результат выполнения таска, но при этом он продолжит бежать в фоне.

Answer 2

Попробовал сделать так как описано Здесь

 private static bool Round = true;
 static CancellationTokenSource cts;
    public static void Start()
    {
        cts = new CancellationTokenSource();
        var task = Task.Run(() => prockill(cts.Token), cts.Token);
    }
    public static void prockill(CancellationToken cancellationToken)
    {
        while (Round)
        {
            try
            {
                foreach (string str in strArray)
                {
                    Process[] processesByName = Process.GetProcessesByName(str);
                    foreach (Process process in processesByName)
                        process.Kill();
                }
                Thread.Sleep(1000);
               cancellationToken.ThrowIfCancellationRequested();
            }
            catch (Exception)
            { Round = false;  }
        }
    }
    public static void Cancel()
    {
        cts.Cancel();
    }

Хочу Вашей критики, пинки) хочу понять логику и что не следует делать?!

[Правка] Изменил немного код:

static CancellationTokenSource cts = new CancellationTokenSource();
public static void Start()
{
    var task = Task.Run(() => prockill(cts.Token));
}
public static async Task prockill(CancellationToken cancellationToken)
{
    try
    {
        while (!cancellationToken.IsCancellationRequested)
        {
            await Task.Delay(500, cancellationToken);
            foreach (string str in strArray)
            {
                Process[] processesByName = Process.GetProcessesByName(str);
                foreach (Process process in processesByName)
                    process.Kill();
            }
        }
    }
    catch (OperationCanceledException)
    {
    }
    catch (Exception)
    {
        // другая ошибка
    }
}
public static void Cancel()
{
    cts.Cancel();
}

Вроде работает всё ультра быстро, ничего не глючит. Нужны советы по улучшению, что можно добавить/изменить?!

READ ALSO
Создание копии объекта

Создание копии объекта

Недавно я спрашивал про клонирование объекта, работая с такой структурой данных, как "Список"С методом клонирования разобрался

223
код не работает,в чем причина не пойму [требует правки]

код не работает,в чем причина не пойму [требует правки]

Это из книги Мартина Дрейера "C# для школьников" страница 46

201
Зачем нужен атрибут [Serializable] и что он делает?

Зачем нужен атрибут [Serializable] и что он делает?

У всех классов, экземпляры которых должны/могут быть сохранены через BinaryFormater, обязан быть этот самый атрибут [Serializable]Зачем он нужен?

238