Skip to content

Instantly share code, notes, and snippets.

@danzuep
Last active March 27, 2023 10:09
Show Gist options
  • Save danzuep/fa42d3e893c2813ec02a4f9bf5efcb26 to your computer and use it in GitHub Desktop.
Save danzuep/fa42d3e893c2813ec02a4f9bf5efcb26 to your computer and use it in GitHub Desktop.
Class for asynchronous cached eager initialization of objects.
using System.Runtime.CompilerServices;
/// <summary>
/// EagerLoad<T> provides support for asynchronous cached eager initialization. This type is fully threadsafe.
/// Lazy<T> is for caching a value and synchronizing multiple threads attempting to get at that cached value.
/// Task<T> is for representing an asynchronous operation and making its result available in the future.
/// <see href="https://devblogs.microsoft.com/pfxteam/asynclazyt/"/>
/// <seealso href="https://blog.stephencleary.com/2012/08/asynchronous-lazy-initialization.html"/>
/// <seealso href="https://github.com/StephenCleary/AsyncEx/blob/master/src/Nito.AsyncEx.Coordination/AsyncLazy.cs"/>
/// </summary>
public sealed class EagerLoad
{
/// <summary>
/// The underlying lazy task.
/// </summary>
private readonly Lazy<Task> _instance;
/// <summary>
/// Initializes a new instance of the <see cref="AsyncLazy&lt;T&gt;"/> class.
/// </summary>
/// <param name="factory">The asynchronous delegate that is invoked on a background thread to produce the value when it is needed.</param>
public EagerLoad(Func<Task> factory)
{
_instance = new Lazy<Task>(() => Task.Run(factory));
_ = _instance.Value; // eager load
}
// Asynchronously await the initialized task.
public async ValueTask Complete()
{
if (!_instance.IsCompleted)
await _instance.Value.ConfigureAwait(false);
}
public ConfiguredTaskAwaitable ConfigureAwait(bool continueOnCapturedContext) => _instance.Value.ConfigureAwait(continueOnCapturedContext);
/// <summary>
/// Asynchronous infrastructure support. This method permits instances of <see cref="AsyncLazy&lt;T&gt;"/> to be awaited.
/// </summary>
//[EditorBrowsable(EditorBrowsableState.Never)]
public TaskAwaiter GetAwaiter() => _instance.Value.GetAwaiter();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment