Why CancellationToken is separate from CancellationTokenSource?

后端 未结 5 1321
夕颜
夕颜 2020-12-02 06:22

I\'m looking for a rationale of why .NET CancellationToken struct was introduced in addition to CancellationTokenSource class. I understand how

5条回答
  •  忘掉有多难
    2020-12-02 07:12

    I had the exact question and I wanted to understand the rationale behind this design.

    The accepted answer got the rationale exactly right. Here's the confirmation from the team who designed this feature (emphasis mine):

    Two new types form the basis of the framework: A CancellationToken is a struct that represents a ‘potential request for cancellation’. This struct is passed into method calls as a parameter and the method can poll on it or register a callback to be fired when cancellation is requested. A CancellationTokenSource is a class that provides the mechanism for initiating a cancellation request and it has a Token property for obtaining an associated token. It would have been natural to combine these two classes into one, but this design allows the two key operations (initiating a cancellation request vs. observing and responding to cancellation) to be cleanly separated. In particular, methods that take only a CancellationToken can observe a cancellation request but cannot initiate one.

    Link: .NET 4 Cancellation Framework

    In my opinion, the fact that CancellationToken can only observe the state and not change it, is extremely critical. You can hand out the token like a candy and never worry that someone else, other than you, will cancel it. It protects you from hostile third party code. Yes, the chances are slim, but I personally like that guarantee.

    I also feel that it makes the API cleaner and avoids accidental mistake and promotes better component design.

    Let's look at public API for both of these classes.

    CancellationToken API

    CancellationTokenSource API

    If you were to combine them, when writing LongRunningFunction, I will see methods like those multiple overloads of 'Cancel' which I should not be using. Personally, I hate to see Dispose method as well.

    I think the current class design follows 'pit of success' philosophy, it guides developers to create better components which can handle Task cancellation and then instrument them together in numerous way to create complicated workflows.

    Let me ask you a question, have you wondered what is the purpose of token.Register? It didn't make sense to me. And then I read Cancellation in Managed Threads and everything became crystal clear.

    I believe that the Cancellation Framework Design in TPL is absolutely top notch.

提交回复
热议问题