AsyncLazy<T> Class
Definition
Provides support for asynchronous lazy initialization: a value is produced at most once, on first access, and the resulting task is cached and shared by every awaiter.
public sealed class AsyncLazy<T>
Type Parameters
TThe type of the lazily produced value.
- Inheritance
-
AsyncLazy<T>
- Inherited Members
- Extension Methods
Examples
private readonly AsyncLazy<Config> _config =
new(async () => await LoadConfigAsync());
public async Task<int> GetTimeoutAsync()
{
Config config = await _config; // factory runs once, result is cached
return config.TimeoutSeconds;
}
Remarks
AsyncLazy<T> is the asynchronous analogue of Lazy<T>. It wraps a Lazy<T> of Task<TResult> with ExecutionAndPublication, so the factory runs exactly once even under concurrent first access. The produced Task<TResult> is cached and may be awaited any number of times, which is why this type exposes Task<TResult> rather than a single-await ValueTask<TResult>.
When constructed from a synchronous Func<TResult>, the factory is offloaded to the thread pool via Run<TResult>(Func<TResult>) so a blocking or CPU-bound factory does not run inline on the first awaiter. A factory that throws produces a faulted task that is cached; every awaiter then observes the same exception.
The shared computation is not canceled by any single caller. Use GetValueAsync(CancellationToken) to abandon an individual wait without affecting the shared factory. A factory that attempts to obtain the value of the same instance while it is still being produced is detected and fails fast with InvalidOperationException rather than deadlocking.
Constructors
AsyncLazy(Func<Task<T>>)
Initializes a new instance of the AsyncLazy<T> class that produces its value with an asynchronous factory.
public AsyncLazy(Func<Task<T>> taskFactory)
Parameters
Exceptions
- ArgumentNullException
taskFactoryis null.
AsyncLazy(Func<T>)
Initializes a new instance of the AsyncLazy<T> class that produces its value with a synchronous factory offloaded to the thread pool.
public AsyncLazy(Func<T> valueFactory)
Parameters
valueFactoryFunc<T>The delegate invoked once to produce the value.
Exceptions
- ArgumentNullException
valueFactoryis null.
Properties
IsValueCreated
Gets a value indicating whether the factory has been invoked.
public bool IsValueCreated { get; }
Property Value
IsValueFactoryCompleted
Gets a value indicating whether the factory has finished producing the value (successfully or with a fault).
public bool IsValueFactoryCompleted { get; }
Property Value
Value
Gets the cached task that produces the value, invoking the factory on first access.
public Task<T> Value { get; }
Property Value
- Task<T>
The shared Task<TResult> representing the lazily produced value.
Exceptions
- InvalidOperationException
The value factory accessed the value of the same instance while it was being produced.
Methods
ConfigureAwait(bool)
Configures how the await on the lazily produced value is continued.
public ConfiguredTaskAwaitable<T> ConfigureAwait(bool continueOnCapturedContext)
Parameters
continueOnCapturedContextbooltrue to marshal the continuation back to the captured context; otherwise, false.
Returns
- ConfiguredTaskAwaitable<T>
A configured awaitable for the cached value task.
Exceptions
- InvalidOperationException
The value factory accessed the value of the same instance while it was being produced.
GetAwaiter()
Gets an awaiter that resolves to the lazily produced value, enabling await on the instance directly.
public TaskAwaiter<T> GetAwaiter()
Returns
- TaskAwaiter<T>
A TaskAwaiter<TResult> for the cached value task.
Exceptions
- InvalidOperationException
The value factory accessed the value of the same instance while it was being produced.
GetValueAsync(CancellationToken)
Asynchronously gets the lazily produced value, abandoning only this caller's wait if the token is canceled.
public Task<T> GetValueAsync(CancellationToken cancellationToken)
Parameters
cancellationTokenCancellationTokenA token used to cancel this caller's wait.
Returns
- Task<T>
A Task<TResult> that completes with the shared value.
Examples
// Abandon only this caller's wait on timeout; the shared factory keeps running for others.
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
Config config = await lazy.GetValueAsync(cts.Token);
Remarks
Cancellation cancels only the returned wait; the shared initialization continues for other callers.
Exceptions
- OperationCanceledException
cancellationTokenwas canceled before the value became available.- InvalidOperationException
The value factory accessed the value of the same instance while it was being produced.
Applies to
| Product | Versions |
|---|---|
| .NET | 8, 10 |