Skip to content

IPool API

Mark Lauter edited this page Jun 15, 2026 · 2 revisions

IPool API

IPool<TPoolItem> is the surface you inject. It declares three operations, a set of diagnostic counters, and implements IDisposable. TPoolItem is constrained to a reference type (where TPoolItem : class). For usage guidance, see Leasing and releasing; this page is the signature-level reference.

Methods

LeaseAsync

ValueTask<TPoolItem> LeaseAsync();
ValueTask<TPoolItem> LeaseAsync(CancellationToken cancellationToken);

Borrows an item. Returns an idle item, creates one if the pool is below MaxSize, or waits for a release until LeaseTimeout elapses or the token is canceled. The parameterless overload uses CancellationToken.None.

  • Throws ObjectDisposedException when the pool is disposed.
  • Throws TaskCanceledException when LeaseTimeout elapses.
  • Throws OperationCanceledException when cancellationToken is canceled.

Release

void Release(TPoolItem item);

Returns a leased item. If a lease is waiting, the item is handed to it directly; otherwise it becomes idle. Synchronous by design — the return enqueues the item and frees a permit, neither of which awaits.

  • Throws ArgumentNullException when item is null.
  • Throws ObjectDisposedException when the pool is disposed.

Release each leased item exactly once. The pool tracks no ownership; a double release corrupts the pool — see Avoiding footguns.

Clear

void Clear();

Disposes every idle item, then refills the pool to MinSize, capped by free capacity so it never exceeds MaxSize. Leased items are unaffected and re-enter on release. Queued lease requests are served by those returns, not by this call.

  • Throws ObjectDisposedException when the pool is disposed.

Scoped leasing

LeaseScopeAsync is an extension method in PoolLeaseExtensions, not a member of the interface. It wraps a lease in a disposable Lease<TPoolItem>:

ValueTask<Lease<TPoolItem>> LeaseScopeAsync<TPoolItem>(
    this IPool<TPoolItem> pool,
    CancellationToken cancellationToken = default)
    where TPoolItem : class;

Lease<TPoolItem> exposes the item and returns it on dispose:

  • Item — the leased item. Throws ObjectDisposedException after the lease is disposed.
  • Dispose() — returns the item to the pool exactly once; idempotent. If the pool was disposed while the item was out on lease, the item is disposed here instead.

A Lease garbage-collected without being disposed is recorded on the pool.leases.leaked counter. See Leasing and releasing.

Counters

All counters are read-only and derived from live pool state.

  • int ItemsAllocated — items the pool owns, leased plus idle.
  • int ItemsAvailable — allocated items that are idle and not leased.
  • int ActiveLeases — items currently leased out (ItemsAllocated minus ItemsAvailable).
  • int QueuedLeases — lease requests waiting for a release.
  • string Name — the pool name, of the form "{typeof(TPoolItem).Name}.Pool".

For production observability, prefer the Metrics instruments over polling these.

Disposal

IPool<TPoolItem> is IDisposable. Disposing the pool disposes its idle items only; items leased out at that moment belong to the caller. See Avoiding footguns.

Clone this wiki locally