This documentation is also published as Markdown for efficient machine reading: the whole site is indexed at /llms.txt, and every page has a clean Markdown copy at the same URL with .md appended. These are generated from the same source and cost far fewer tokens to read than this rendered HTML.

Skip to main content Skip to navigation

AsyncLazy Pennington.Infrastructure

Thread-safe asynchronous lazy initialization. The factory is queued onto the thread pool on first access; subsequent accesses return the same task. A faulted task is evicted so the next access retries.

Use GetAwaiter (i.e. await asyncLazy) from async contexts. Pennington has no sync-over-async on this type in production code; if a new consumer reaches for asyncLazy.Task.GetAwaiter().GetResult(), make its caller async instead — that's the pattern that exhausts thread-pool budget and occasionally deadlocks under hostile schedulers.

Properties

Task Task<T>
Returns the underlying task. Starts the factory on a thread-pool thread the first time it is accessed; subsequent accesses replay the same task. A previously-faulted task is evicted so the next access retries.

Constructors

AsyncLazy

#
public AsyncLazy`1(Func<Task<T>> factory)

Initializes the instance with a factory invoked on first access.

Parameters

factory Func<Task<T>>

Methods

GetAwaiter

#
public TaskAwaiter<T> GetAwaiter()

Lets the lazy be awaited directly: var value = await asyncLazy;.

Returns

TaskAwaiter<T>

Pennington.Infrastructure.AsyncLazy

namespace Pennington.Infrastructure;

/// Thread-safe asynchronous lazy initialization. The factory is queued onto the thread pool on first access; subsequent accesses return the same task. A faulted task is evicted so the next access retries. Use GetAwaiter (i.e. await asyncLazy) from async contexts. Pennington has no sync-over-async on this type in production code; if a new consumer reaches for asyncLazy.Task.GetAwaiter().GetResult(), make its caller async instead — that's the pattern that exhausts thread-pool budget and occasionally deadlocks under hostile schedulers.
public class AsyncLazy
{
    /// Initializes the instance with a factory invoked on first access.
    
public AsyncLazy`1(Func<Task<T>> factory)
; /// Lets the lazy be awaited directly: var value = await asyncLazy;.
public TaskAwaiter<T> GetAwaiter()
; /// Returns the underlying task. Starts the factory on a thread-pool thread the first time it is accessed; subsequent accesses replay the same task. A previously-faulted task is evicted so the next access retries.
public Task<T> Task { get; }
}