Skip to content

Instantly share code, notes, and snippets.

@StephenCleary
Created September 23, 2012 22:15
Show Gist options
  • Save StephenCleary/3773234 to your computer and use it in GitHub Desktop.
Save StephenCleary/3773234 to your computer and use it in GitHub Desktop.
AsyncLazy
using System;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
/// <summary>
/// Provides support for asynchronous lazy initialization. This type is fully threadsafe.
/// </summary>
/// <typeparam name="T">The type of object that is being asynchronously initialized.</typeparam>
public sealed class AsyncLazy<T>
{
/// <summary>
/// The underlying lazy task.
/// </summary>
private readonly Lazy<Task<T>> instance;
/// <summary>
/// Initializes a new instance of the <see cref="AsyncLazy&lt;T&gt;"/> class.
/// </summary>
/// <param name="factory">The delegate that is invoked on a background thread to produce the value when it is needed.</param>
public AsyncLazy(Func<T> factory)
{
instance = new Lazy<Task<T>>(() => Task.Run(factory));
}
/// <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 AsyncLazy(Func<Task<T>> factory)
{
instance = new Lazy<Task<T>>(() => Task.Run(factory));
}
/// <summary>
/// Asynchronous infrastructure support. This method permits instances of <see cref="AsyncLazy&lt;T&gt;"/> to be await'ed.
/// </summary>
public TaskAwaiter<T> GetAwaiter()
{
return instance.Value.GetAwaiter();
}
/// <summary>
/// Starts the asynchronous initialization, if it has not already started.
/// </summary>
public void Start()
{
var unused = instance.Value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment