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?
Jörg B.
source share