取消正在執行的任務我有我需要依次處理(但在一個單獨的工作線程,從而保持用戶界面的響應)的項目清單。重要的是要注意的是,這些項目可以運行很長時間(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
不正確。
有沒有辦法對我來說,安全地取消/停止當前正在執行的任務?
是的,只是代碼正是你想要的。沒有魔法,祕密簡單的方法。您必須指定將支持中斷的每個任務在哪裏以及如何中斷,可能通過在方便的位置檢查其任務結構來查看它是否被取消。 –
在你的'ProcessItem'方法中,你可以傳入'CancellationToken'並定期調用'ThrowIfCancellationRequested'。 –
問題是我無法以任何方式重新設計ProcessItem()。 – davenewza