Что такое «CancellationToken» в TaskFactory.Startnew () используется для?

StackOverflow https://stackoverflow.com/questions/3689765

Вопрос

http://msdn.microsoft.com/en-us/library/dd988458.aspx.

Уполномоченный:

Итак, давайте обсудим эту статью тогда: http://msdn.microsoft.com/en-us/library/dd977396.aspx.

Я немного изменил этот код:

    static void Main()
    {

        var tokenSource2 = new CancellationTokenSource();
        CancellationToken ct = tokenSource2.Token;

        var task = Task.Factory.StartNew(() =>
        {

            // Were we already canceled?
            ct.ThrowIfCancellationRequested();

            bool moreToDo = true;
            Thread.Sleep(5000);
            while (moreToDo)
            {

                // Poll on this property if you have to do
                // other cleanup before throwing.
                if (ct.IsCancellationRequested)
                {
                    Console.WriteLine("exit");
                    // Clean up here, then...
                    ct.ThrowIfCancellationRequested();
                }

            }
        }, tokenSource2.Token); // this parameter useless

        Console.WriteLine("sleep");
        Thread.Sleep(2000);
        Console.WriteLine("cancel");

        tokenSource2.Cancel();

        // Just continue on this thread, or Wait/WaitAll with try-catch:
        try
        {
            task.Wait();
        }
        catch (AggregateException e)
        {
            foreach (var v in e.InnerExceptions)
            {
                Console.WriteLine(e.Message + " " + v.Message);
            }
        }

        Console.ReadKey();
    }

Уполномоченный: Ну, это только изменения task.IsCanceled, который является ИМХО бесполезным, из-за того, что я все еще должен реализовать все вручную.

Это было полезно?

Решение

Из-за комментариев я размещаю другой ответ.

Рассмотрим следующий код:

var tokenSource = new CancellationTokenSource();
CancellationToken ct = tokenSource.Token;

tokenSource.Cancel(); 

var task = Task.Factory.StartNew(() =>
{    
  // Were we already canceled?
  ct.ThrowIfCancellationRequested();
  // do some processing
});

Даже если звонок tokenSource.Cancel() Выдается до начала задачи, вы все равно выделите рабочую нить из пула резьбы, поэтому вы будете тратить некоторые системные ресурсы.

Но когда вы указываете аргумент Token в Task.Factory.StartNew, задача будет отменена немедленно, не выделяя рабочей нити.

Другие советы

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

CancellationTokens лучше, чем более простые конструкции, такие как ManualResetEvent Для отключения сигнализации операции, поскольку вы можете казаться или объединить их, например, вы можете иметь один для общего выключения приложения, и вы можете объединить его с одним для отмены определенной задачи. Задача должна только посмотреть на один CancellationToken но вы можете отменить его из любого CancellationTokenSource.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top