`CancellationTokenSource.TryReset` 的用例是什么?
What is the use-case for `CancellationTokenSource.TryReset`?
CancellationTokenSource
有一个 TryReset()
成员。 documentation 看起来如此严格,让我想知道它为什么存在。
- 它只有在没有人已经调用
Cancel()
时才有效。
- 它仅在使用其令牌发出的任何先前异步操作完成时才有效,这意味着(我认为)我需要挂在我的 Task 对象上以跟踪它是否仍然 运行
- 当其他人试图取消操作时调用是不安全的,需要
那么为什么人们会为 TryReset
烦恼呢?为什么不简单地为每个异步操作创建一个全新的 CancellationTokenSource
,然后在操作完成并且不再需要取消后将其丢弃? CancellationTokenSource
创建一个非常昂贵的对象吗?
- 在这里你可以找到 original issue
- 在这里你可以找到 related pull request
让我在这里引用问题的背景和动机部分
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 backing CancellationTokenSource
(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 the RequestAborted
token is accessed. If Kestrel attempted to reuse the CTS backing the RequestAborted
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 calling CancelAfter(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 causing CancelAfter()
to no-op. This is demonstrated in the second HttpClient
usage example.
CancellationTokenSource
有一个 TryReset()
成员。 documentation 看起来如此严格,让我想知道它为什么存在。
- 它只有在没有人已经调用
Cancel()
时才有效。 - 它仅在使用其令牌发出的任何先前异步操作完成时才有效,这意味着(我认为)我需要挂在我的 Task 对象上以跟踪它是否仍然 运行
- 当其他人试图取消操作时调用是不安全的,需要
那么为什么人们会为 TryReset
烦恼呢?为什么不简单地为每个异步操作创建一个全新的 CancellationTokenSource
,然后在操作完成并且不再需要取消后将其丢弃? CancellationTokenSource
创建一个非常昂贵的对象吗?
- 在这里你可以找到 original issue
- 在这里你可以找到 related pull request
让我在这里引用问题的背景和动机部分
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.