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

CancellationTokenSourcePool

using System; using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; namespace Polly.Utils { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] internal abstract class CancellationTokenSourcePool { [System.Runtime.CompilerServices.Nullable(0)] private sealed class DisposableCancellationTokenSourcePool : CancellationTokenSourcePool { private readonly TimeProvider _timeProvider; public DisposableCancellationTokenSourcePool(TimeProvider timeProvider) { _timeProvider = timeProvider; } protected override CancellationTokenSource GetCore(TimeSpan delay) { if (!IsCancellable(delay)) return new CancellationTokenSource(); return TimeProviderTaskExtensions.CreateCancellationTokenSource(_timeProvider, delay); } public override void Return(CancellationTokenSource source) { source.Dispose(); } } [System.Runtime.CompilerServices.Nullable(0)] private sealed class PooledCancellationTokenSourcePool : CancellationTokenSourcePool { public static readonly PooledCancellationTokenSourcePool SystemInstance = new PooledCancellationTokenSourcePool(TimeProvider.get_System()); private readonly ObjectPool<CancellationTokenSource> _pool; public PooledCancellationTokenSourcePool(TimeProvider timeProvider) { _pool = new ObjectPool<CancellationTokenSource>(() => new CancellationTokenSource(), (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 ((object)timeProvider == (object)TimeProvider.get_System()) return PooledCancellationTokenSourcePool.SystemInstance; return new DisposableCancellationTokenSourcePool(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; } } }