CancellationTokenSource
has a TryReset()
member. The documentation appears so strict as to make me wonder why it exists.
Cancel()
on it.So why would people bother with TryReset
? Why not simply create a brand new CancellationTokenSource
for every asynchronous operation and then throw it away after the operation completes and cancellation is no longer needed? Is CancellationTokenSource
a terribly expensive object to create?
Let me quote here the Background and Motivation section of the issue
When a library or framework exposes a
CancellationToken
that usually does not get canceled (e.g.HttpContext.RequestAborted
) they often still need to dispose the backingCancellationTokenSource
(CTS) after an operation completes rather than reusing it in order to account for callers that might never dispose their registrations.To use the
RequestAborted
example, Kestrel disposes the backing CTS after every request where theRequestAborted
token is accessed. If Kestrel attempted to reuse the CTS backing theRequestAborted
token for future requests in order to reduce allocations, it would risk leaking any undisposed registrations and triggering the undisposed registrations when unrelated requests are aborted.Another scenario where people want to be able to "reset" a CTS is after calling
CancelAfter()
. This can already be achieved by callingCancelAfter(Timeout.Infinite)
, but that's not necessarily obvious unless you read the docs.TryReset()
is something that would immediately make sense in this scenario when looking at intellisense completions.Another benefit is that it's immediately obvious if resetting failed. If you try resetting a timeout with
CancelAfter()
, you have to check after the call to verify their was no cancellation before or during the call causingCancelAfter()
to no-op. This is demonstrated in the secondHttpClient
usage example.