运行时任务被取消,我的程序无法继续运行

Task is cancelled when it is running,My program can't go on running

CancellationTokenSource cts = new CancellationTokenSource();

List<Task> allTask = new List<Task>();

for (int i = 0; i < 10000; i++)
{
    int j = i;
    allTask.Add(Task.Factory.StartNew(() =>
    {
        if (cts.Token.IsCancellationRequested)
        {
            return;
        }
        cts.Cancel();
        Thread.Sleep(1000);
        Console.WriteLine("I'm doing it");
    }, cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Current));
}

Task.WaitAll(allTask.ToArray());

Console.WriteLine("Implementation success!");

Console.ReadKey();

关于问题,取消任务后,我的程序没有继续运行。这是为什么?我明确取消了。 为什么我的程序没有输出"Implementation success"?

这是设计使然;调用 cts.Cancel() 将始终在 WaitAll 调用上抛出 TaskCanceledException。因此,您的代码将 1000 个任务排入队列,等待所有任务,抛出异常,然后您的程序终止。

查看 TPL 文档 https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/how-to-cancel-a-task-and-its-children#example 明确告诉您如何使用 AggregateException 处理程序检查 InnerExceptions.[=19 中的 TaskCancelledException 来处理这种情况=]

如果您希望您的代码到达 "Implementation Success" w/正确处理取消,请添加一个 AggregateException 处理程序:

    CancellationTokenSource cts = new CancellationTokenSource();

    List<Task> allTask = new List<Task>();

    for (int i = 0; i < 10000; i++)
    {
        int j = i;
        allTask.Add(Task.Factory.StartNew(() =>
        {
            if (cts.Token.IsCancellationRequested)
            {
                return;
            }
            cts.Cancel();
            Thread.Sleep(1000);
            Console.WriteLine("I'm doing it");
        }, cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Current));
    }

    try
    {
        Task.WaitAll(allTask.ToArray());
    }
    catch (AggregateException ex)
    {
        //handle the cancelled tasks here, though you are doing it on purpose...
        Console.WriteLine("One or more tasks were cancelled.");
    }

    Console.WriteLine("Implementation success!");

    Console.ReadKey();

我有类似的问题,我的任务工作时间太长,解决方法如下: 在 class xxx 我有私人 collection :

private List<TaskWork> _taskCollection = new List<TaskWork>();

向列表添加新任务:

var cancellationToken = new CancellationTokenSource();
cancellationToken.CancelAfter(10000);

var taskWork = new TaskWorkVM
{
    CancellationToken = cancellationToken.Token,
    StartTime = DateTime.Now
};
taskWork.Task = Task.Run(() => { [some_work]; }, taskWork.CancellationToken);
_taskCollection.Add(taskWork);

检查是否完成了某些任务,并从 collection 中删除:

var completedTask = _taskCollection.Where(t => t.Task.IsCompleted).FirstOrDefault();

if (completedTask != null)
{
    _taskCollection.Remove(completedTask);
}

你可以做while来检查列表,我觉得简单的while就够了:

while (_taskCollection.Count() > 0)
{
    //do something
}

任务 class 有其他标志 IsCanceled 或者您可以使用任务状态。