Fixed undo action (ThrowForNonSuccess)

This is a continuation of this question: Multiple continuation of the task

I changed my code as in the answer, but now I get TaskCancelledExceptions when I try to start tasks.

 public virtual async Task RunAsync(TaskWithProgress task) { Show(); TaskIsRunning(); await SetCompletedHandler(TaskComplete()); await SetCancelledHandler(TaskCancelled()) await SetFaultedHandler(TaskFaulted()); await task; Close(); } 

however, the following code does not. I am a little fixated on why.

 public virtual Task RunAsync(TaskWithProgress task) { Show(); TaskIsRunning(); SetCompletedHandler(TaskComplete()); SetCancelledHandler(TaskCancelled()) SetFaultedHandler(TaskFaulted()); return task; } 

The calling code basically includes the following:

 await progressDialog.RunAsync(task); 

Edit:

I do not cancel cancellationtoken anywhere, so I do not see why this throws this exception.

The three SetXXXHandler () methods basically execute the following code with different continuation status:

 task.ContinueWith(_ => action(), CancellationToken.None, TaskContinuationOptions.OnlyOnCanceled, this.Scheduler); 

The stack trace is here:

  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at FugroDXExt.frmBaseProgressAsync.<RunAsync>d__7.MoveNext() in d:\C#\FugroDXExt\trunk\frmBaseProgressAsync.cs:line 92 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at FCP.Forms.frmProcessing.<mnuApplyCenteredSmoothing_ItemClick>d__34.MoveNext() in d:\C#\FCP\FCP\Forms\frmProcessing.cs:line 578 

Close() just closes the form. If I delete this line, the same thing will happen.

+6
source share
1 answer

You say that SetCancelledHandler just adds a continuation to the task. I assume that the same RunAsync task gets as a parameter, although I canโ€™t tell your code how SetCancelledHandler gets the task to continue (I assume we are missing code). Anyway...

You register 3 continuations of the task that will be executed when the task is completed, it is canceled and a failure. Now let me assume that the original task completed successfully without canceling. This means that 2 of your continuations ( OnCanceled and OnFaulted ) will not be executed, because they should not be. The way to tell the task not to run in TPL is to cancel it, and this will happen automatically.

The difference between the two code snippets is that in the first you await execution of tasks and they are canceled, which explains your exception. In the second fragment, you do not expect to continue, just the initial task, which successfully completed.

PS: I think the second option is more appropriate. You do not need to await all these sequels. You want them to run if they need to.

TL DR: You await canceled the continuation task. The continuation task, not the original, is an exception.

+8
source

All Articles