Dav*_*New 1 .net c# multithreading asynchronous task-parallel-library
我有一个需要按顺序处理的项目列表(但在单独的工作线程上以保持 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());
}
Run Code Online (Sandbox Code Playgroud)
现在,我使用 aCancellationToken来取消队列的处理(有一个“取消处理”按钮)。
问题是这不会取消当前正在执行的任务。如果CancellationTokenSource.Cancel()被调用,则队列中等待执行的所有任务将被取消,并且它们的项目currentItem.State将被设置为State.Cancelled,这是正确的。问题是取消时正在执行的任务将继续执行,直到完成然后设置为State.Completeor State.Failed。这并不理想,原因有两个:(1) 任务取消后仍在运行,(2) 状态未设置为State.Cancelled因为t.IsCanceled不是 true。
有没有办法让我安全地取消/停止当前正在执行的任务?
任务支持优雅的取消模式。CancellationToken只是一个令牌。它不会中断任何正在执行的代码或中止线程。您应该自己在任务正文中检查此令牌。
需要记住的一点:如果您想取消当前任务,请通过CancellationToken.ThrowIfCancellationRequested方法取消它,而不仅仅是从任务主体中退出。