There is an article that describes the .NET Cancellation design here which is worth a read. In relation to your question, the following is asked in the comments:
Just out of interest, why is the CancellationToken a value type?
and the questioner proposes an alternative implementation with a single shared instance of CancellationToken as a reference type.
And the response by Mike Liddell:
This would certainly work and is largely equivalent (and we implemented it this way during early prototyping), but we went with the current design for two particular reasons:
– only one class instance per CTS/Token, hence less GC pressure.
– we consolidate all of the state and most of the logic onto CTS. The split arrangement was a somewhat more convoluted.
I would note that the current value type implementation is exactly the same size as a reference so there isn't any additional copying overhead. It also prevents some additional boilerplate null checks in user-code, especially when making the token an optional parameter.