我在代码中使用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();
现在我的问题是,当 _cancellationTokenSource.Cancel() 方法在某个地方被调用时(在“取消”按钮的 .Click 事件处理程序中),该特定 loadingDataCancelledTask 的主体/方法不会被调用。
我在这里做错了什么?我正在使用并交出相同的 _cancellationTokenSource.Token 实例...和其他所有事情('writingLoadedDataToGridTask' 和 'loadingDataFaulted' 任务以及以下的 'Task.Factory.ContinueWhenAny(new[] { writingLoadedDataToGridTask, loadingDataCancelledTask, loadingDataFaulted }, task =>...' 块)实际上都起作用。只有取消操作没有起作用。有人看到/知道为什么吗?