Continuing TPL cancellation never caused a canceled task

I have the following setting in my code that uses TPL:

  • One field in my class: private CancellationTokenSource _cancellationTokenSource;
  • This CancellationTokeSource gets instatiated every time I create a TPL task that uses this particular cancelationtoken

Actual TPL tasks are as follows:

var dataRetrievalTask = new Task<List<myType>>(() => { // retrieve data and do something foreach (var a in retrievalMethod()) { if (_cancellationTokenSource.Token.IsCancellationRequested) _cancellationTokenSource.Token.ThrowIfCancellationRequested(); // do something if not cancelled } } return filledListOfMyType; }, _cancellationTokenSource.Token); // define what shall happen if data retrievel finished without any problems var writingLoadedDataToGridTask = dataRetrievalTask.ContinueWith(task => { // do something in case we ran to completion without error }, _cancellationTokenSource.Token, TaskContinuationOptions.OnlyOnRanToCompletion, currentScheduler); // what to do in case cancellation was performed var loadingDataCancelledTask = dataRetrievalTask.ContinueWith(task => { someLabel.Text = "Data retrieval canceled."; },_cancellationTokenSource.Token, TaskContinuationOptions.OnlyOnCanceled, currentScheduler); // what to do in case an exception / error occured var loadingDataFaulted = dataRetrievalTask.ContinueWith(task => { someLabel.Text = string.Format("Data retrieval ended with an Error."); }, _cancellationTokenSource.Token, TaskContinuationOptions.OnlyOnFaulted, currentScheduler); // when any of the continuation tasks ran through, reset ui controls / buttons etc Task.Factory.ContinueWhenAny(new[] { writingLoadedDataToGridTask, loadingDataCancelledTask, loadingDataFaulted }, task => { // reset controls and all that }, _cancellationTokenSource.Token, TaskContinuationOptions.None, currentScheduler); dataRetrievalTask.Start(); 

Now my problem is that when the _cancellationTokenSource.Cancel () method is called somewhere (in the Cancel-button.Click event handler), that particular object / method loadDataCancelledTask is not called.

What am I doing wrong here? I use and pass the same instance of _cancellationTokenSource.Token ... and everything else (tasks "writeLoadedDataToGridTask" and "loadingDataFaulted" and the next task Task.Factory.ContinueWhenAny (new [] {writeLoadedDataToGridTask, loadingDataCancelledTault, loadingData} =) . ') really works. Only cancellation does not. Does anyone see / know why?

+7
source share
1 answer

Your cancellation renewal is canceled because it uses the same cancellation token.

If you think about it, it makes sense: when you say “I want to cancel all processing”, you really get what you ask for. All processing stops, including updating the user interface.

The solution is to not use the undo token to continue undo, error, and ContinueWhenAny . Thus, these continuations are always executed.

+8
source

All Articles