任务取消时,任务ContinueWith不会触发

时间:2017-04-12 20:20:56

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

我正在使用命令行实用程序开发内部应用程序来控制PDF文档的操作。我正在尝试构建一个CommandManager类,允许一次运行多个操作,允许它们被取消等等。

我有一个包装器对象(PdfCommandTask),用于管理我想要执行的命令,取消源和任务。然后,我会在我的UI中保留这些列表。 ProcessAsync是一个基于任务的解决方案,用于运行我在此处找到的Process对象:

ProcessStartInfo hanging on "WaitForExit"? Why?

我对TPL相当苛刻,我遇到了一个问题,即当我取消任务时,下面代码中的延续不会触发...它会触发正常任务完成或不同的错误条件。

在调试器中,它遵循Exception catch路径,设置我的结果对象,并点击第一个任务的return语句......但是继续进行而不进入延续并移出方法。

我经历了几次迭代并阅读了很多帖子,但我还没弄清楚我的问题。任何想法将不胜感激。

注意:我意识到AggregateException / Exception处理可能是多余的,我只是试图在我的测试中覆盖我的基础。

感谢。

    public void Execute(PdfCommand command)
    {
        PdfCommandResult result = command.Valid();
        if (!result.Success)
        {
            CommandCompleted?.Invoke(this, result);
            return;
        }

        command.BuildCommands();

        var cmdTask = new PdfCommandTask(command);
        var token = cmdTask.CancelTokenSource.Token;

        // Add the task to the task list
        CommandList.Add(cmdTask);

        cmdTask.Task = Task.Run<PdfCommandResult>(async () =>
         {
             Debug.Print("Spinning up task...");

             var pdfResult = new PdfCommandResult();

             List<Task> taskList = new List<Task>();
             foreach (var cmd in command.Commands)
             {
                 var procTask = ProcessAsync.StartProcess(Pdftk, cmd, cmdTask.CancelTokenSource, PdftkPath);
                 taskList.Add(procTask);
             }

             try
             {
                 if (token.IsCancellationRequested)
                     token.ThrowIfCancellationRequested();

                 await Task.WhenAll(taskList);
             }
             catch (AggregateException e)
             {
                 Debug.Print("AggregateException thrown.");
                 if (e.InnerException is OperationCanceledException)
                     pdfResult = new PdfCommandResult("The task was cancelled.");
                 else
                     pdfResult = new PdfCommandResult("The task faulted... Error: " + e.InnerException);
             }
             catch (Exception e)
             {
                 Debug.Print("Exception thrown.");
                 if (e is OperationCanceledException)
                     pdfResult = new PdfCommandResult("The task was cancelled.");
                 else
                     pdfResult = new PdfCommandResult("The task faulted... Error: " + e);
             }

             return pdfResult;

         }, token).ContinueWith((prevTask) =>
         {
             Debug.Print("ContinueWith fired.");

             // Get the previous task result
             result = prevTask.Result;

             // Remove the task from the task list
             CommandList.Remove(cmdTask);

             // Let anyone listening know that the command completed (it may have been cancelled or faulted)
             CommandCompleted?.Invoke(this, result);
         }, token, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
    }

0 个答案:

没有答案