我有一个项目列表,我需要按顺序处理(但在一个单独的工作线程上,以保持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());
}
现在,我使用CancellationToken
取消队列处理(有一个“取消处理”按钮)。
问题是这不会取消当前正在执行的任务。如果调用CancellationTokenSource.Cancel()
,那么等待在队列中执行的所有任务都将被取消,其项目currentItem.State
将设置为State.Cancelled
,这是正确的。问题是,取消时执行的任务将继续执行,直到完成,然后设置为State.Complete
或State.Failed
。这有两个原因并不理想:(1)取消后任务仍在运行,(2)状态未设置为State.Cancelled
,因为t.IsCanceled
不正确。
我有办法安全取消/停止当前正在执行的任务吗?
答案 0 :(得分:4)
任务支持优雅的取消模式。 CancellationToken
只是令牌。它不会中断任何正在执行的代码或中止线程。您应该自己在任务正文中检查此令牌。
要记住的一点是:如果您想取消当前任务,请通过CancellationToken.ThrowIfCancellationRequested
方法取消,而不仅仅是退出任务正文。
答案 1 :(得分:2)
查看有关“任务取消”的msdn文章。 http://msdn.microsoft.com/en-us/library/dd997396.aspx 您所要做的就是检查Task的工作方法中是否取消了Task。将检查取消代码放在方法的关键区域。 希望它有所帮助!