Skip to content

[API Proposal]: Introduce TimeProvider extension method to create a CTS to be cancelled after a specified time period. #85080

@tarekgh

Description

@tarekgh

Background and motivation

A new constructor called CancellationTokenSource(TimeSpan, TimeProvider) has been introduced for creating a CTS object that automatically gets cancelled after a specified period using the TimeProvider. However, this constructor is only available on .NET 8.0. For users who are using TimeProvider on down-level versions, they will need to write their own code to achieve the same functionality. An example of such code is given below.

        private static void CancelAfter(TimeProvider provider, CancellationTokenSource cts, TimeSpan delay)
        {
            if (provider == TimeProvider.System)
            {
                cts.CancelAfter(delay);
            }
            else
            {
                ITimer timer = provider.CreateTimer(s => ((CancellationTokenSource)s).Cancel(), cts, delay, Timeout.InfiniteTimeSpan);
                cts.Token.Register(t => ((ITimer)t).Dispose(), timer);
            }
        }

The experience would be unsatisfactory when users want to write a ns2.0 library code that works in all supported framework versions.

API Proposal

namespace System.Threading.Tasks
{
    public static class TimeProviderTaskExtensions
    {

        /// <summary>Initializes a new instance of the <see cref="CancellationTokenSource"/> class that will be canceled after the specified <see cref="TimeSpan"/>. </summary>
        /// <param name="timeProvider">The <see cref="TimeProvider"/> with which to interpret the <paramref name="delay"/>. </param>
        /// <param name="delay">The time interval to wait before canceling this <see cref="CancellationTokenSource"/>. </param>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="delay"/>'s <see cref="TimeSpan.TotalMilliseconds"/> is less than -1 or greater than <see cref="uint.MaxValue"/> - 1. </exception>
        /// <remarks>
        /// The countdown for the delay starts during the call to the constructor.  When the delay expires,
        /// the constructed <see cref="CancellationTokenSource"/> is canceled if it has
        /// not been canceled already. Subsequent calls to CancelAfter will reset the delay for the constructed
        /// <see cref="CancellationTokenSource"/> if it has not been canceled already.
        /// </remarks>
        public static CancellationTokenSource CreateCancellationTokenSource(this TimeProvider timeProvider, TimeSpan delay) ;
    }
}

API Usage

CancellationTokenSource  cts = TimeProvider.System.CreateCancellationTokenSource(TimeSpan.FromMilliseconds(100));

....

cts.Task.WaitAsync(CancellationToken.None);

Alternative Designs

No response

Risks

No response

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions