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 under /_llms/. 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; }
}