protected override void Dispose(bool disposing)
        {
            if (!disposing)
            {
                base.Dispose(disposing);
                return;
            }

            if (disposed)
            {
                return;
            }
            disposed = true;

            var message = $"{Name}.Dispose()";

            DisposeFunc baseDispose     = () => base.Dispose(true);
            DisposeFunc originalDispose = baseDispose;

            var action = Interlocked.Exchange(ref disposeAction, null);

            if (action?.Dispose != null)
            {
                message    += " - action";
                baseDispose = () => action.Dispose(originalDispose);
            }

            Dispose_internal(message, baseDispose);
        }
 void Dispose_internal(string message, DisposeFunc func)
 {
     LogDebug(message);
     try {
         func();
         LogDebug($"{message} done");
     } catch (Exception ex) {
         if (IgnoreErrors)
         {
             return;
         }
         LogDebug($"{message} failed: {ex}");
         throw;
     }
 }