使用LimitedConcurrencyLevelTask​​Scheduler和Task.Start与TaskFactory.StartNew

时间:2017-09-05 22:49:13

标签: c# .net multithreading task task-parallel-library

我使用LimitedConcurrencyLevelTaskScheduler。当一个案例中Task构造函数创建任务而另一个案例中TaskFactory.StartNew()创建任务时,我不理解为什么任务取消以不同方式工作。

class Program
{
    static void Main()
    {
        Action longAction =
            () =>
            {
                Task.Delay(5000).Wait();
                Console.WriteLine("Long action is finished.");
            };
        Action actionToBeCanceled = () => Console.WriteLine("Never see this");

        CancellationTokenSource cts = new CancellationTokenSource();
        // only one task can be running at once
        TaskScheduler lclts = new LimitedConcurrencyLevelTaskScheduler(1);

        // case A
        Task longTask = new Task(longAction, CancellationToken.None, 
            TaskCreationOptions.None);
        Task taskToBeCanceled = new Task(actionToBeCanceled, cts.Token, 
            TaskCreationOptions.None);
        longTask.Start(lclts);
        taskToBeCanceled.Start(lclts);

        // case B
        //TaskFactory factory = new TaskFactory(lclts);
        //Task longTask = factory.StartNew(longAction);
        //Task taskToBeCanceled = factory.StartNew(actionToBeCanceled, cts.Token);

        taskToBeCanceled.ContinueWith(
            t => Console.WriteLine("taskToBeCanceled is completed. Status=" + t.Status),
            CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Default);

        Task.Delay(2000).Wait();
        cts.Cancel();
        cts.Dispose();
        Console.WriteLine("After cancel. Status=" + taskToBeCanceled.Status);
        Console.ReadLine();
    }
}

案例A中的输出:

After cancel. Status=Canceled
taskToBeCanceled is completed. Status=Canceled
Long action is finished.

案例B中的输出:

After cancel. Status=WaitingToRun
Long action is finished.
taskToBeCanceled is completed. Status=Canceled

如果在taskToBeCanceled之后立即取消cts.Cancel()。但是在案例B中,它在longTask完成后被取消。它是如何工作的?在案例A中,某些内容会调用TaskScheduler.TryDequeue()。但为什么TaskFactory.StartNew不会发生这种情况?我应该怎样做(使用TaskFactory.StartNew)在cts.Cancel之后立即取消任务?

0 个答案:

没有答案