0

순차적으로 처리해야하는 항목 목록이 있지만 (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.StateState.Cancelled으로 설정됩니다. 문제는 취소 할 때까지 실행중인 작업이 완료 될 때까지 계속 실행 한 다음 State.Complete 또는 State.Failed으로 설정해야한다는 것입니다. 이는 다음 두 가지 이유로 이상적이지 않습니다. (1) 작업이 취소 후 계속 실행 중입니다. (2) t.IsCanceled이 true가 아니기 때문에 상태가 State.Cancelled으로 설정되지 않았습니다.

안전하게 현재 실행중인 작업을 취소/중지 할 수있는 방법이 있습니까?

+1

그래, 정확히 원하는대로 코드를 작성하십시오. 마술, 비밀 쉬운 방법이 없습니다. 편리한 지점에서 태스크 구조를 점검하여 취소되었는지 확인하여 인터럽트를 지원할 각 태스크가 중단 될 위치와 방법을 지정해야합니다. –

+1

'ProcessItem' 메쏘드에서'CancellationToken'을 전달하고 주기적으로'ThrowIfCancellationRequested'를 호출 할 수 있습니다. –

+0

문제는 어떤 식 으로든 ProcessItem()을 리엔지니어링 할 수 없다는 것입니다. – davenewza

답변

4

작업은 우아한 취소 패턴을 지원합니다. CancellationToken토큰입니다. 실행 코드를 인터럽트하거나 스레드를 중단하지 않습니다. 이 토큰은 작업 본문에서 직접 확인해야합니다.

기억해야할 점 : 현재 작업을 취소하려면 작업 본문을 종료하는 것뿐만 아니라 CancellationToken.ThrowIfCancellationRequested 메서드를 통해 취소하십시오.

2

작업 취소에 대한 msdn 문서를 확인하십시오. http://msdn.microsoft.com/en-us/library/dd997396.aspx 작업의 작동 방법에서 작업이 취소되었는지 확인하면됩니다. 방법의 중요 영역에 수표 취소 코드를 넣으십시오. 도움이 되었기를 바랍니다.