AsyncLazy disposal

I've made this extension method. Its purpose is to trigger the disposal of a value, stored in a Nito.AsyncEx AsyncLazy, as authored by @StephenCleary.

Is this an approach that makes sense? Is the code good?

using System;

using Nito.AsyncEx;

/// <summary>
/// Extensions to types in the <see cref="Nito.AsyncEx"> namespace.
/// </summary>
public static class NitoAsyncEx
{
/// <summary>
/// Disposes the specified <see cref="AsyncLazy"> value.
/// </summary>
/// <typeparam name="T">The type of the lazy value.</typeparam>
/// <param name="asyncLazy> The asynchronous lazy.</param>
/// <returns>When disposal is complete.</returns>
this AsyncLazy<T> asyncLazy) where T : IDisposable
{
if (asyncLazy.Id != 0)
{
(await asyncLazy).Dispose();
}
}
}


It's potentially dangerous to only conditionally dispose of the resource. If you don't dispose it if the resource was never initialized in the first place then you run the risk of some code actually initializing it later, and then not disposing of that resource.

The safer design would be to wrap the object, rather than just having this one extension method.

public class DisposableAsyncLazy<T> : IDisposable
where T : IDisposable
{
private AsyncLazy<T> lazy;
private bool disposed = false;
public DisposableAsyncLazy(Func<T> factory)
{
lazy = new AsyncLazy<T>(factory);
}
{
lazy = new AsyncLazy<T>(factory);
}
public int Id
{
get
{
return lazy.Id;
}
}
{
if (!disposed)
return await lazy;
else
throw new ObjectDisposedException("DisposableAsyncLazy");
}
public void Start()
{
if (!disposed)
lazy.Start();
else
throw new ObjectDisposedException("DisposableAsyncLazy");
}

public async void Dispose()
{
disposed = true;
if (lazy.Id != 0)
(await lazy).Dispose();

}
}


(Note you can make DisposableAsyncLazy awaitable, rather than having a method/property produce a task, if you want to take the time to do so.)

• +1, the only downside I see, is that this will mask the debugger help built into Nito.AsyncEx.AsyncLazy which is non trivial, for me at least, to add to a composition external to the Nito.AsyncEx assembly. (The [DebuggerDisplay] stuff). nitoasyncex.codeplex.com/SourceControl/latest#Source/… Sep 5, 2014 at 8:40
• @Jodrell That's the upside of open source content. You actually can put this type inside the same assembly as the type it's composing, if you're willing to re-compile the assembly. That said, I'm not particularly familiar with that feature, so I couldn't say if there's a better option. Sep 5, 2014 at 13:57