Продолжение отмены TPL никогда не вызывалось для отмененной задачи

В моем коде, использующем TPL, есть следующая настройка:

  • Одно поле в моем классе: private CancellationTokenSource _cancellationTokenSource;
  • Этот CancellationTokeSource инициализируется каждый раз, когда я создаю задачу TPL, которая использует этот конкретный маркер отмены.

На самом деле задачи TPL выглядят так:

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();

Теперь моя проблема заключается в том, что когда где-то вызывается метод _cancellationTokenSource.Cancel() ( в обработчике событий .Click кнопки Cancel) это конкретное тело/метод loadingDataCancelledTask не вызывается.

Что я здесь делаю не так? Я использую и передаю один и тот же экземпляр _cancellationTokenSource.Token... и все остальное (задачи "writingLoadedDataToGridTask" и "loadingDataFaulted" и следующие "Task.Factory.ContinueWhenAny (new [] {writingLoadedDataToGridTask, loadingDataCancelledTask, loadingDataFaulted}, задача => ...' block) действительно работают. Только отмена не работает. Кто-нибудь видит/знает почему?

7
задан usr 12 May 2012 в 11:22
поделиться