Skip to content

Instantly share code, notes, and snippets.

@mrpmorris
Created September 9, 2022 14:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrpmorris/b78c18737f98750373f852562f06d817 to your computer and use it in GitHub Desktop.
Save mrpmorris/b78c18737f98750373f852562f06d817 to your computer and use it in GitHub Desktop.
DisposableAction
public sealed class DisposableCallback : IDisposable
{
private readonly Action Action;
private readonly string CallerFilePath;
private readonly int CallerLineNumber;
private readonly bool WasCreated;
private bool IsDisposed;
/// <summary>
/// Creates an instance of the class
/// </summary>
/// <param name="id">
/// An Id that is included in the message of exceptions that are thrown, this is useful
/// for helping to identify the source that created the instance that threw the exception.
/// </param>
/// <param name="action">The action to execute when the instance is disposed</param>
public DisposableCallback(
Action action,
[CallerFilePath] string callerFilePath = "",
[CallerLineNumber] int callerLineNumber = 0)
{
if (action is null)
throw new ArgumentNullException(nameof(action));
Action = action;
CallerFilePath = callerFilePath;
CallerLineNumber = callerLineNumber;
WasCreated = true;
}
/// <summary>
/// Executes the action when disposed
/// </summary>
public void Dispose()
{
if (IsDisposed)
throw new ObjectDisposedException(
nameof(DisposableCallback),
$"Attempt to call {nameof(Dispose)} twice on {nameof(DisposableCallback)}");
IsDisposed = true;
GC.SuppressFinalize(this);
Action();
}
/// <summary>
/// Throws an exception if this object is collected without being disposed
/// </summary>
/// <exception cref="InvalidOperationException">Thrown if the object is collected without being disposed</exception>
~DisposableCallback()
{
if (!IsDisposed && WasCreated)
throw new InvalidOperationException($"{nameof(DisposableCallback)} created in"
+ $"{CallerFilePath}:{CallerLineNumber} was not disposed");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment