我有一个需要按顺序处理的项目列表(但在单独的工作线程上以保持 UI 响应能力)。需要注意的重要一点是,这些项目可以运行很长时间(5 - 10 秒)。
Task<bool> currentTask = null;
foreach (var item in items)
{
var currentItem = item;
// Add a new task to the sequential task queue
if (currentTask == null)
currentTask = Task.Factory.StartNew<bool>(() =>
{
return currentItem.ProcessItem();
}, processCancelTokenSource.Token);
else
currentTask = currentTask.ContinueWith<bool>(t =>
{
return currentItem.ProcessItem();
}, processCancelTokenSource.Token);
// Update UI after each task completes
currentTask.ContinueWith(t =>
{
if (t.IsCanceled)
currentItem.State = State.Cancelled;
else
{
if (t.Result)
currentItem.State = State.Complete;
else
currentItem.State = State.Failed;
}
},TaskScheduler.FromCurrentSynchronizationContext());
}
现在,我正在使用 aCancellationToken
来取消队列的处理(有一个“取消处理”按钮)。
问题是这不会取消当前正在执行的任务。如果CancellationTokenSource.Cancel()
被调用,那么队列中所有等待执行的任务都会被取消,并且它们的itemcurrentItem.State
会被设置为State.Cancelled
,这是正确的。问题是取消时正在执行的任务将继续执行,直到完成,然后设置为State.Complete
or State.Failed
。这并不理想,原因有两个:(1)取消后任务仍在运行,(2)状态未设置为State.Cancelled
因为t.IsCanceled
不正确。
有没有办法让我安全地取消/停止当前正在执行的任务?