TPLを利用するコードに次の設定があります。
- 私のクラスの1つのフィールド:private CancellationTokenSource _cancellationTokenSource;
- このCancellationTokeSourceは、その特定のcancellationtokenを使用する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イベントハンドラー内)で呼び出されたときに、その特定のloadingDataCancelledTaskの本体/メソッドが呼び出されないことです。
私はここで何が間違っているのですか?同じ_cancellationTokenSource.Tokenインスタンス...と他のすべて('writingLoadedDataToGridTask'および'loadingDataFaulted'タスクとそれに続く'Task.Factory.ContinueWhenAny(new [] {writingLoadedDataToGridTask、loadingDataCancelledTask、loadingDataFaulted}、task => ...'ブロック)は実際に機能します。キャンセルのみは機能しません。誰かが理由を見たり知ったりしますか?