順番に処理する必要があるアイテムのリストがあります (ただし、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
です。これは 2 つの理由で理想的ではありません: (1) キャンセル後もタスクが実行中である、(2) がtrue でないState.Cancelled
ために状態が設定されてt.IsCanceled
いない。
現在実行中のタスクを安全にキャンセル/停止する方法はありますか?