C#
에서는 비동기 작업에 대한 취소요청을 CancellationTokenSource
와 CancellationToken
을 이용해서 할 수 있게 되어있다.
지금까지 어렴풋하게 알고 있는 사실은 CancellationToken
은 CancellationTokenSource
라는 것에 의해 생성되고 CancellationTokenSource
에서 Cancel()
을 호출하면 CancellationTokenSource
가 발행했던 CancellationToken
이 모두 취소 된다는 것이다.
CancellationToken
을 사용하는 비동기 함수에서는 CancellationToken
이 취소 되었는지 확인하고 취소 여부에 따라 올바로 함수에서 리턴할 수 있도록 작성해줘야 한다.
하지만 저자는 여기서 의문점이 드는 점이 있었다.
CancellationToken
비동기 매소드에 파라미터로 전달되는 형식으로 사용되는데 이 객체는 구조체로써 값 타입니다.
구조체를 파라미터로 넘기면 값이 복사되고(call by value) 함수 밖에서 파라미터로 전달 한 값의 값을 아무리 변경하여도 함수 안에서는 전혀 영향이 없다.
이렇게 값 타입으로 넘겨지는 CancellationToken이 어떻게 함수 밖에서 변경되는 취소 상태에대해서 올바로 통지 받을 수 있는 것일까?
어떻게 동작하는지 알기 위해 실제로 소스코드를 확인해 보자!
CancellationTokenSource
에서 CancellationToken
을 생성하는 프로퍼티는 아래와 같이 작성 되어 있다.
CancellationTokenSource
에서 CancellationToken
을 반환하는 Token 프로퍼티는 new 키워드를 이용해서 CancellationToken
을 생성한다.
여기서 주목해야할 점은 파라미터로
CancellationToken
을 만든CancellationTokenSource
의 주소 값을 넘긴다는 것이다.
그럼 CancellationToken
은 파라미터로 받은 값을 어떻게 사용할까?
소스코드를 확인해보면 답이 있을 것이다.
CancellationToken
은 자기 자신을 만든 CancellationTokenSource
를 private filed로 가지고 있고 CancellationToken
에게 IsCancellationRequested
프로퍼티로 취소 여부를 묻는다면 자기 자신을 만든 CancellationTokenSource
의 IsCancellationRequested
의 값을 가져와 리턴하는 것이다.
-. CancellationToken
이 만들어질 때 자기 자신을 만든 CancellationTokenSource
의 주소 값을 파라미터로 받아 갖고있는다.
-. CancellationToken
의 취소 여부를 묻는다면 자기 자신을 만든 CancellationTokenSource
의 취소 여부값을 리턴해준다.
이렇게 되면
CancellationToken
이 아무리 구조체여도 내부에 자기 자신을 만든CancellationTokenSource
를 참조하고 있으므로 함수 밖에서CancellationTokenSource
의Cancel()
함수가 호출된다면CancellationToken
에서 취소 여부를 알 수 있게 된다.