C\#CancellationToken 과 CancellationTokenSource 의 용법 에 대한 상세 한 설명

CancellationToken
CancellationToken 에는 현재 CancellationToken 이 취소 상태 인지 아 닌 지 를 나타 내 는 구조 함수 가 있 습 니 다.또한 CancellationToken 은 하나의 구조 체 이기 때문에 빈 매개 변수의 구조 함수 도 있다. 

    public CancellationToken();//      ,       ,       
    public CancellationToken(bool canceled);
속성 은 다음 과 같 습 니 다:

    //    ,      CancellationToken,  CancellationToken            ,               CancellationToken
    public static CancellationToken None { get; }
    //    CancellationToken       
    public bool CanBeCanceled { get; }
    //    CancellationToken         
    public bool IsCancellationRequested { get; }
    // CancellationToken   WaitHandle  ,CancellationToken              WaitHandle   
    public WaitHandle WaitHandle { get; }
상용 방법:

    // CancellationToken     
    public CancellationTokenRegistration Register(Action callback);
    public CancellationTokenRegistration Register(Action callback, bool useSynchronizationContext);
    public CancellationTokenRegistration Register([NullableAttribute(new[] { 1, 2 })] Action<object?> callback, object? state);
    public CancellationTokenRegistration Register([NullableAttribute(new[] { 1, 2 })] Action<object?> callback, object? state, bool useSynchronizationContext);
    // CancellationToken       ,  System.OperationCanceledException  
    public void ThrowIfCancellationRequested();
자주 사용 하 는 등록 리 셋 방법 은 위의 4 개의 Register 방법 입 니 다.그 중에서 callback 은 리 셋 실행 의뢰 입 니 다.useSynchronization Context 는 동기 화 컨 텍스트 를 사용 할 지 여 부 를 표시 합 니 다.state 는 리 셋 의뢰 에 전 달 된 매개 변수 값 입 니 다.
또한,Register 방법 은 CancellationTokenRegistration 구조 체 를 되 돌려 줍 니 다.리 셋 을 등록 한 후에 CancellationTokenRegistration 의 Unregister 방법 으로 등록 을 취소 할 수 있 습 니 다.이 Unregister 방법 은 bool 값 을 되 돌려 줍 니 다.취소 에 성공 하면 true 로 돌아 갑 니 다.취소 에 실패 하면(예 를 들 어 리 셋 이 실 행 된 경우)false 로 돌아 갑 니 다.

    CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
    var cancellationTokenRegistration = cancellationTokenSource.Token.Register(() =>
    {
        Console.WriteLine("Canceled");//         
    });

    //cancellationTokenSource.Cancel();
    //var result = cancellationTokenRegistration.Unregister();//result = false

    var result = cancellationTokenRegistration.Unregister();//result = true
   cancellationTokenSource.Cancel();
 위 에서 언급 한 바 와 같이 CancellationToken 은 구조 함 수 를 사용 하여 직접 구 조 를 할 수 있 고 하나의 매개 변 수 를 입력 하여 현재 상 태 를 나 타 낼 수 있다.주의해 야 할 것 은 CancellationToken 의 상 태 는 최대 한 번 까지 바 꿀 수 있다 는 것 이다.즉,취소 되 지 않 은 상태 가 취소 되 었 다 는 것 이다.
구조 시 true 로 들 어 오 면 CancellationToken 이 취 소 된 상태 이 고 이때 등 록 된 리 셋 은 즉시 실 행 됩 니 다.

    CancellationToken cancellationToken = new CancellationToken(true);
    cancellationToken.Register(() =>
    {
        Console.WriteLine("Canceled");//         Canceled
    });
그러나 만약 에 구조 할 때 false 가 들 어 오 면 CancellationToken 이 취소 되 지 않 은 상태 에 있다 는 것 을 의미 합 니 다.이때 등 록 된 것 은 모두 트리거 상태 에 있 습 니 다.

    CancellationToken cancellationToken = new CancellationToken(false);
    cancellationToken.Register(() =>
    {
        Console.WriteLine("Canceled");//          
    });
Register 방법 으로 등 록 된 서 비 스 는 한 번 만 실 행 됩 니 다!
그러나 일반적으로 false 구조 로 들 어 오 는 CancellationToken 은 촉발 할 방법 이 없 기 때문에 촉발 할 수 없다 고 볼 수 있 습 니 다!그래서 일반적으로 저 희 는 구조 함수 로 CancellationToken 을 만 들 지 않 고 CancellationTokenSource 대상 을 사용 하여 CancellationToken 을 가 져 옵 니 다.
CancellationTokenSource
CancellationTokenSource 는 CancellationToken 의 컨트롤 러 로 이해 할 수 있 습 니 다.언제 취소 상태의 대상 이 될 지 제어 할 수 있 습 니 다.CancellationToken 형식의 속성 Token 이 있 습 니 다.CancellationTokenSource 가 만 들 면 이 Token 도 만 들 고 Token 은 이 CancellationTokenSource 와 연 결 됩 니 다.

    //  Token         
    public bool IsCancellationRequested { get; }
    //CancellationToken   
    public CancellationToken Token { get; }
CancellationTokenSource 대상 을 직접 만 들 고 시간 대 를 지정 할 수 있 습 니 다.이 시간 이 지나 면 CancellationTokenSource 가 자동 으로 취 소 됩 니 다.
Cancellation TokenSource 의 취 소 는 네 가지 방법 이 있 습 니 다.

    //    
    public void Cancel();
    //    
    public void Cancel(bool throwOnFirstException);
    //         
    public void CancelAfter(int millisecondsDelay);
    //         
    public void CancelAfter(TimeSpan delay);
Cancel 과 두 개의 Cancel After 방법 은 특별한 것 이 없습니다.주로 지연 효과 가 있 습 니 다.주의해 야 할 것 은 Cancel 의 두 과부하 간 의 차이 입 니 다.
우선,CancellationToken 상 태 는 한 번 만 바 꿀 수 있 습 니 다.(취소 되 지 않 고 취소 되 었 습 니 다)CancellationToken 이 취소 되 었 을 때,그 중 에 등 록 된 리 셋 이 즉시 실 행 됩 니 다!취소 되 지 않 은 상태 에 있 을 때 등 록 된 리 셋 은 모두 실 행 될 때 까지 기다 릴 것 이다.
주의해 야 할 것 은 취소 되 지 않 은 상태 에서 여러 개의 리 셋 을 등록 할 때 실행 할 때 스 택 과 유사 한 구조 순서 로 먼저 등록 한 후에 실행 하 는 것 입 니 다.
한편,CancellationToken 의 Register 는 여러 개의 리 셋 을 등록 할 수 있 습 니 다.그러면 그들 은 모두 이상 을 던 질 수 있 습 니 다.throw On First Exception 매개 변 수 는 첫 번 째 오류 가 발생 했 을 때의 처리 행 위 를 표시 합 니 다.
throw OnFirst Exception=true 는 현재 발생 한 이상 을 즉시 던 지고 후속 리 셋 은 실행 을 취소 합 니 다.

    CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
    try
    {
        cancellationTokenSource.Token.Register(() =>
        {
            throw new Exception("1");
        });
        cancellationTokenSource.Token.Register(() =>
        {
            throw new Exception("2");//    
        });

        cancellationTokenSource.Cancel(true);
    }
    catch (Exception ex)
    {
        //ex is System.Exception("1")
    }
 throw On First Exception=false 는 현재 리 셋 의 이상 을 건 너 뛰 고 발 효 된 리 셋 을 계속 실행 하 며 모든 리 셋 이 실 행 된 후에 모든 이상 을 하나의 System.AgregateException 이상으로 포장 하여 던 집 니 다!

    CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
    try
    {
        cancellationTokenSource.Token.Register(() =>
        {
            throw new Exception("1");
        });
        cancellationTokenSource.Token.Register(() =>
        {
            throw new Exception("2");
        });

        cancellationTokenSource.Cancel(false);//   cancellationTokenSource.Cancel()
    }
    catch (Exception ex)
    {
        //ex is System.AggregateException:[Exception("2"),Exception("1")]
    }
 CancellationTokenSource 는 다른 CancellationToken 과 연결 하여 새로운 CancellationToken 을 생 성 할 수 있 습 니 다.다른 CancellationToken 이 취소 되면 현재 CancellationTokenSource 에서 취소 동작 을 자동 으로 실행 합 니 다!  
사용 필드 1
비동기 작업 을 만 들 때 CancellationToken 에 들 어 갈 수 있 습 니 다.비동기 작업 이 실행 대기 상태 에 있 을 때 CancellationToken 을 취소 상태 로 설정 하여 비동기 작업 을 취소 할 수 있 습 니 다.

    CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
    var task = new Task(() =>
    {
        Thread.Sleep(1500);//   2    
        Console.WriteLine("Execute Some Code");
    }, cancellationTokenSource.Token);

    task.Start();//  ,      

    //    ,    task  
    cancellationTokenSource.Cancel();
    Thread.Sleep(1000);//  1 
    Console.WriteLine("Task  :" + task.Status);//Canceled
 그러나 항상 우리 의 취소 동작 이 그렇게 제때에 실행 되 지 않 을 수도 있 습 니 다.만약 에 비동기 가 이미 실행 되 었 고 취소 할 때 무효 입 니 다.이것 은 우리 가 비동기 의뢰 에서 검 측 해 야 합 니 다.

    CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
    var task = new Task(() =>
    {
        Thread.Sleep(1500);//   2    
        cancellationTokenSource.Token.ThrowIfCancellationRequested();
        Console.WriteLine("Execute Some Code");
    }, cancellationTokenSource.Token);

    task.Start();//  ,      

    Thread.Sleep(1000);////         ,    task  
    cancellationTokenSource.Cancel();
    Thread.Sleep(1000);//  1 
    Console.WriteLine("Task  :" + task.Status);//Canceled
사용 필드 2
 때때로,우 리 는 특정한 시간 을 촉발 한 후에 일부 코드 기능 을 실행 할 수 있 기 를 희망 합 니 다.그러나 비동기 환경 에서 우 리 는 실행 할 코드 가 이미 준비 되 었 는 지 보장 할 수 없습니다.예 를 들 어 우 리 는 Close 방법 이 있 습 니 다.Close 를 호출 한 후에 닫 힌 상 태 를 표시 합 니 다.예 를 들 어 우리 가 상당 한 프로그램 이 닫 힌 상태 에 있 을 때 알림 을 실행 하 는 것 과 같 습 니 다.우 리 는 이벤트 모델 을 사용 하거나 Close 방법 으로 이벤트 의뢰 를 전달 하거나 템 플 릿 디자인 과 같은 모델 로 실현 하고 싶 을 수도 있 습 니 다.

    class Demo
    {
        public void Close(Action callback)
        {
            //  
            Thread.Sleep(3000);

            callback?.Invoke();//    
        }
    }
혹은

    class Demo
    {
        public event Action Callback;

        public void Close()
        {
            //  
            Thread.Sleep(3000);

            Callback?.Invoke();//    
        }
    }
그러나 문제 가 있 습 니 다.만약 에 매개 변 수 를 입력 하거나 이벤트 모델 을 사용 하 는 것 이 라면 앞에서 말 했 듯 이 비동기 환경 에서 실행 할 코드 가 준비 되 어 있 는 지 보장 할 수 없습니다.Close 방법 을 실행 할 때 프로그램 이 아직 리 셋 을 등록 하지 않 았 을 수도 있 습 니 다.
이 때 CancellationToken 을 사용 하여 이 문 제 를 해결 할 수 있 습 니 다.
주 는 Token 속성 에 리 셋 을 등록 해 야 합 니 다.Close 가 언제 실 행 될 지 관심 을 가 질 필요 가 없습니다.
사용 필드 3
때때로 우 리 는 이 보 무한 순환 의 방법 을 써 서 몇 가지 문 제 를 처리 할 수 있다.그러나 우 리 는 방법 이 외부 에서 그것 을 멈 출 수 있 기 를 바란다.이때 우 리 는 Cancellation TokenSource 로 돌아 가 실현 할 수 있다.

        public CancellationTokenSource Listen()
        {
            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();

            //      
            Task.Run(() =>
            {
                while (true)
                {
                    cancellationTokenSource.Token.ThrowIfCancellationRequested();

                    //        
                    Thread.Sleep(1000);
                    Console.WriteLine("Run");
                }
            });

            return cancellationTokenSource;
        }
이상 은 C\#CancellationToken 과 CancellationTokenSource 의 용법 에 대한 상세 한 내용 입 니 다.C\#CancellationToken 과 CancellationTokenSource 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 하 세 요!

좋은 웹페이지 즐겨찾기