<PackageReference Include="Polly.Core" Version="8.5.1" />

CancellationTokenSourcePool

using System; using System.Runtime.CompilerServices; using System.Threading; namespace Polly.Utils { [NullableContext(1)] [Nullable(0)] internal abstract class CancellationTokenSourcePool { [Nullable(0)] private sealed class PooledCancellationTokenSourcePool : CancellationTokenSourcePool { public static readonly PooledCancellationTokenSourcePool SystemInstance = new PooledCancellationTokenSourcePool(TimeProvider.System); private readonly ObjectPool<CancellationTokenSource> _pool; public PooledCancellationTokenSourcePool(TimeProvider timeProvider) { _pool = new ObjectPool<CancellationTokenSource>(() => new CancellationTokenSource(System.Threading.Timeout.InfiniteTimeSpan, timeProvider), (CancellationTokenSource cts) => true); } protected override CancellationTokenSource GetCore(TimeSpan delay) { CancellationTokenSource cancellationTokenSource = _pool.Get(); if (IsCancellable(delay)) cancellationTokenSource.CancelAfter(delay); return cancellationTokenSource; } public override void Return(CancellationTokenSource source) { if (source.TryReset()) _pool.Return(source); else source.Dispose(); } } public static CancellationTokenSourcePool Create(TimeProvider timeProvider) { if (timeProvider == TimeProvider.System) return PooledCancellationTokenSourcePool.SystemInstance; return new PooledCancellationTokenSourcePool(timeProvider); } public CancellationTokenSource Get(TimeSpan delay) { if (delay <= TimeSpan.Zero && delay != System.Threading.Timeout.InfiniteTimeSpan) throw new ArgumentOutOfRangeException("delay", delay, "Invalid delay specified."); return GetCore(delay); } protected abstract CancellationTokenSource GetCore(TimeSpan delay); public abstract void Return(CancellationTokenSource source); protected static bool IsCancellable(TimeSpan delay) { return delay != System.Threading.Timeout.InfiniteTimeSpan; } } }