我的代码中有以下使用 TPL 的设置:
- 我班上的一个字段:private CancellationTokenSource _cancellationTokenSource;
- 每次我创建使用该特定取消令牌的 TPL 任务时,此 CancellationTokeSource 都会被激活
实际的 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();
现在我的问题是,当某处(在取消按钮的 .Click 事件处理程序中)调用 _cancellationTokenSource.Cancel() 方法时,不会调用特定的 loadingDataCancelledTask 的主体/方法。
我在这里做错了什么?我正在使用并移交相同的 _cancellationTokenSource.Token 实例...以及其他所有内容(“writingLoadedDataToGridTask”和“loadingDataFaulted”任务以及以下“Task.Factory.ContinueWhenAny(new[] { writingLoadedDataToGridTask, loadingDataCancelledTask, loadingDataFaulted }, task => ...'块)确实有效。只有取消没有。有人看到/知道为什么吗?