我使用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
之后立即取消任务?