Background and motivation
I maintain a custom cancelation token that can be converted to and from System.Threading.CancellationToken. Since the CancellationTokenSource.TryReset API was introduced in .Net 6, I have had to do some heavy-handed work to re-register my token to keep listening for the cancelation. Being able to listen to an event for when the source is reset would allow me to only re-register at that time, and remove a lot of code.
API Proposal
namespace System.Threading;
public struct CancellationToken
{
public event Action OnReset;
}
API Usage
public class MyCustomToken
{
public class MyCustomToken(CancellationToken token)
{
token.OnReset += () => token.Register(OnCanceled);
token.Register(OnCanceled);
}
private void OnCanceled()
{
// Logic for custom cancelation,
// including handling the case of double registration due to a thread race.
}
// Other public methods that are irrelevant for this proposal...
}
Alternative Designs
#60843 Was an idea to have an alternative callback when the callback is unregistered without being invoked, but it wasn't good because it would increase the cost of other more common operations. This proposal deals with that issue by only raising a global event when TryReset is called, instead of individual callbacks for each registration, so other operations aren't affected (and memory increase for the event is minimal).
Risks
Slightly increases memory of CancellationTokenSource.
Possible race condition if TryReset is called on another thread while registering the first time (but that would be a mis-use of the TryReset API, going against the intended use laid out in the documentation, and that's already a possible race condition today).
Background and motivation
I maintain a custom cancelation token that can be converted to and from
System.Threading.CancellationToken. Since theCancellationTokenSource.TryResetAPI was introduced in .Net 6, I have had to do some heavy-handed work to re-register my token to keep listening for the cancelation. Being able to listen to an event for when the source is reset would allow me to only re-register at that time, and remove a lot of code.API Proposal
API Usage
Alternative Designs
#60843 Was an idea to have an alternative callback when the callback is unregistered without being invoked, but it wasn't good because it would increase the cost of other more common operations. This proposal deals with that issue by only raising a global event when
TryResetis called, instead of individual callbacks for each registration, so other operations aren't affected (and memory increase for the event is minimal).Risks
Slightly increases memory of
CancellationTokenSource.Possible race condition if
TryResetis called on another thread while registering the first time (but that would be a mis-use of theTryResetAPI, going against the intended use laid out in the documentation, and that's already a possible race condition today).