0

많은 작업을 동시에 수행 할 수있는 서비스를 받았습니다. 모든 현재 실행중인 작업을 종료해야하는 중단 옵션을 추가하도록 지정되었습니다. 시스템이 이미 구현 되었기 때문에 CancellationTokenSource를 모든 작업에 전달하는 것이 문제가 되었기 때문에 모든 작업에서 취소를 청취하는 하나의 작업 만 만들었습니다. recive를 중단하면 그 토큰은 취소를 보내고 새로운 CancellationTokenSource 인스턴스가 생성됩니다. 취소 할 때까지 모든 작업을 확인하는 데 문제가 발생했습니다. 전에 앞에 CancellationTokenSource의 새 인스턴스가 시작되었습니다.하나의 취소 토큰을 사용하여 모든 작업을 중단하는 중 추가

  1. 가 처음에는 내가 TokenSource.Cancel()가 전송 단지 이벤트이지만은 "고의"갇혀있는 것 같다 생각, 마찬가지로 너무 새로운 작업 :

    Q의 몇

    취소도 받게됩니다. 사실입니까?

  2. 이상적으로 모든 작업에 대해 자신의 취소 토큰 (오른쪽?)이 있어야합니다. 누가 그 토큰을 보유해야합니까? 누가 그 일이나 일 자체를 불러 냈습니까? 일단 퇴장을 보내면 작업이 종료 시점에 도달 할 시점을 알 수 없기 때문에 그 토큰을 영원히 유지해야 할 것입니다.

  3. 이미 실행중인 모든 작업을 모니터링하는 방법이 이미 구현되어 있습니까? 취소가 전송되었습니다. 새 작업을 허용하기 전에 모든 작업이 종료되었는지 확인하겠습니다. 나는 세마포어를 사용했다하지만 초보자 질문 죄송합니다

, 나는 이미 내가 필요로 무엇을 구현 .. 끔찍한 sulotion 모양과 작동,하지만 품질 표준 아래의 방법이며 내가 개선하고자 올바른 방법.

답변

4
  1. 작업은 모든 취소를받지 않았다. 이것은 단지 토큰의 상태 변경 일뿐입니다. 작업이 토큰을 보게되면 취소가있는 경우 요청이 가능하면 작업이 취소 될 수 있습니다.

  2. CancellationTokenstruct이기 때문에 각 작업에는 자체 토큰이 있으며 값으로 복사됩니다. 토큰 (1을보십시오)을보기를 위해 업무는 토큰을 지켜야했다.

  3. 아니요, 작업을 기다려야하며 강제로 작업을 취소 할 수 없습니다. 취소 작업을 사용하면 취소 요청 만 보내고 실행중인 작업은 취소되거나 완료 될 수 있습니다 (구현에 따라 다름). 단지 시작 아직 작업 (실행 대기)이 (가 전혀 시작되지 않습니다) 당신이 찾고있는 이러한 취소를 구현하는 방법을 예를 들어

스케줄러에 의해 취소됩니다없는 매우 간단한 샘플

원래 서비스

public interface IFooService 
{ 
    Task DoAsync(CancellationToken cancellationToken); 
} 

및 취소를 처리 할 하나

public interface ICancelableFooService : IFooService 
{ 
    Task CancelAsync(); 
} 

public class CancelableFooService : ICancelableFooService 
{ 
    private readonly IFooService _foo_service; 
    private readonly object _sync = new object(); 
    private List<Task> _createdtasks = new List<Task>(); 
    private CancellationTokenSource _cts = new CancellationTokenSource(); 

    public CancelableFooService(IFooService foo_service) 
    { 
     _foo_service = foo_service; 
    } 

    public async Task CancelAsync() 
    { 
     _cts.Cancel(); 
     var t = Task.WhenAll(_createdtasks); 
     try 
     { 
      await t; 
     } 
     catch { /* we eat all exceptions here */ } 
     lock(_sync) 
     { 
      _cts = new CancellationTokenSource(); 
      _createdtasks.Clear(); 
     } 
    } 

    public Task DoAsync(CancellationToken cancellationToken) 
    { 
     lock(_sync) 
     { 
      var cts = CancellationTokenSource.CreateLinkedTokenSource(_cts.Token, cancellationToken); 
      var token = cts.Token; 
      var task = _foo_service.DoAsync(token); 
      _createdtasks.Add(task); 
     } 
     return task; 
    } 
} 
+0

우선, 감사합니다. 1.이미 취소 된 TokenSource를 취소 취소 할 수 있습니까? 3. 현재 실행중인 작업을 최소한으로 모니터링 할 수있는 방법이 있습니까? 그래서 모든 작업이 끝났음을 알 수 있습니다. –

+0

@ O.San 왜 "uncancel"하고 싶습니까? CancellationTokenSource를 사용하여 다른 기능을 에뮬레이트하려고합니까? –

+0

@ O.San은 모니터링 할 때 필요하지 않습니다. 'Task.WhenAll'은 모든 작업이 완료 될 때 완료됩니다. –