순차적으로 처리해야하는 항목 목록이 있지만 (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());
}
지금, I 큐의 처리를 취소하는 CancellationToken
사용하고 (「처리 취소 "버튼이있다).
문제는 현재 실행중인 작업을 취소하지 않는다는 것입니다. CancellationTokenSource.Cancel()
이 호출되면 대기열에서 실행 대기중인 모든 작업이 취소되고 해당 항목의 currentItem.State
은 State.Cancelled
으로 설정됩니다. 문제는 취소 할 때까지 실행중인 작업이 완료 될 때까지 계속 실행 한 다음 State.Complete
또는 State.Failed
으로 설정해야한다는 것입니다. 이는 다음 두 가지 이유로 이상적이지 않습니다. (1) 작업이 취소 후 계속 실행 중입니다. (2) t.IsCanceled
이 true가 아니기 때문에 상태가 State.Cancelled
으로 설정되지 않았습니다.
안전하게 현재 실행중인 작업을 취소/중지 할 수있는 방법이 있습니까?
그래, 정확히 원하는대로 코드를 작성하십시오. 마술, 비밀 쉬운 방법이 없습니다. 편리한 지점에서 태스크 구조를 점검하여 취소되었는지 확인하여 인터럽트를 지원할 각 태스크가 중단 될 위치와 방법을 지정해야합니다. –
'ProcessItem' 메쏘드에서'CancellationToken'을 전달하고 주기적으로'ThrowIfCancellationRequested'를 호출 할 수 있습니다. –
문제는 어떤 식 으로든 ProcessItem()을 리엔지니어링 할 수 없다는 것입니다. – davenewza