Dispose pattern - DisposableObject
Firstly, to address inheritance concerns, I use a t4 template to get around the single inheritance problem. ie. for every class where I need to introduce dispose support, I generate the an abstract base class that inherits from that class. Works a treat.

Now, to your code. Here are the things that jump out at me:


Constructors should be protected because the base class is abstract. This would make the code clearer to me, but YMMV.
Lose the whole unmanaged resource tracking. It adds complexity without value. Just call SuppressFinalize() regardless - it's the recommended pattern, anyway.
Your code is not thread-safe. Consider, for example, what happens if multiple threads call Dispose() simultaneously. You're got the potential for multiple calls to DisposeManagedResources() etcetera.


FWIW, here is an example Disposable base class generated by my t4 template:

// Generated by t4 template in Utility project. DO NOT EDIT!
#pragma warning disable 1591, 0612
#region Designer generated code

namespace Foo
{
    using System;
    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis;
    using System.Globalization;
    using System.Threading;
    using Kent.Boogaart.HelperTrinity.Extensions;

    /// &lt;summary&gt;
    /// A useful base class for disposable objects that inherit from &lt;see cref="object"/&gt;.
    /// &lt;/summary&gt;
    /// &lt;remarks&gt;
    /// &lt;para&gt;
    /// This base class simplifies the implementation of disposable objects by providing common functionality such as thread-safety on &lt;see cref="Dispose"/&gt; calls,
    /// and a &lt;see cref="Disposing"/&gt; event for pre-disposal notification.
    /// &lt;/para&gt;
    /// &lt;/remarks&gt;
    public abstract class DisposableBase : object, IDisposable
    {
        private const int DisposalNotStarted = 0;
        private const int DisposalStarted = 1;
        private const int DisposalComplete = 2;

#if DEBUG
        // very useful diagnostics when a failure to dispose is detected
        private readonly StackTrace creationStackTrace;
#endif

        // see the constants defined above for valid values
        private int disposeStage;

#if DEBUG
        /// &lt;summary&gt;
        /// Initializes a new instance of the DisposableBase class.
        /// &lt;/summary&gt;
        protected DisposableBase()
        {
            this.creationStackTrace = new StackTrace(1, true);
        }

        /// &lt;summary&gt;
        /// Finalizes an instance of the DisposableBase class.
        /// &lt;/summary&gt;
        [SuppressMessage("Microsoft.Design", "CA1063", Justification = "The enforced behavior of CA1063 is not thread-safe or full-featured enough for our purposes here.")]
        ~DisposableBase()
        {
            var message = string.Format(CultureInfo.InvariantCulture, "Failed to proactively dispose of object, so it is being finalized: {0}.{1}Object creation stack trace:{1}{2}", this.ObjectName, Environment.NewLine, this.creationStackTrace);
            Debug.Assert(false, message);
            this.Dispose(false);
        }
#endif

        /// &lt;summary&gt;
        /// Occurs when this object is about to be disposed.
        /// &lt;/summary&gt;
        public event EventHandler Disposing;

        /// &lt;summary&gt;
        /// Gets a value indicating whether this object is in the process of disposing.
        /// &lt;/summary&gt;
        protected bool IsDisposing
        {
            get { return Interlocked.CompareExchange(ref this.disposeStage, DisposalStarted, DisposalStarted) == DisposalStarted; }
        }

        /// &lt;summary&gt;
        /// Gets a value indicating whether this object has been disposed.
        /// &lt;/summary&gt;
        protected bool IsDisposed
        {
            get { return Interlocked.CompareExchange(ref this.disposeStage, DisposalComplete, DisposalComplete) == DisposalComplete; }
        }

        /// &lt;summary&gt;
        /// Gets a value indicating whether this object has been disposed or is in the process of being disposed.
        /// &lt;/summary&gt;
        protected bool IsDisposedOrDisposing
        {
            get { return Interlocked.CompareExchange(ref this.disposeStage, DisposalNotStarted, DisposalNotStarted) != DisposalNotStarted; }
        }

        /// &lt;summary&gt;
        /// Gets the object name, for use in any &lt;see cref="ObjectDisposedException"/&gt; thrown by this object.
        /// &lt;/summary&gt;
        /// &lt;remarks&gt;
        /// Subclasses can override this property if they would like more control over the object name appearing in any &lt;see cref="ObjectDisposedException"/&gt;
        /// thrown by this &lt;c&gt;DisposableBase&lt;/c&gt;. This can be particularly useful in debugging and diagnostic scenarios.
        /// &lt;/remarks&gt;
        /// &lt;returns&gt;
        /// The object name, which defaults to the class name.
        /// &lt;/returns&gt;
        protected virtual string ObjectName
        {
            get { return this.GetType().FullName; }
        }

        /// &lt;summary&gt;
        /// Disposes of this object, if it hasn't already been disposed.
        /// &lt;/summary&gt;
        [SuppressMessage("Microsoft.Design", "CA1063", Justification = "The enforced behavior of CA1063 is not thread-safe or full-featured enough for our purposes here.")]
        [SuppressMessage("Microsoft.Usage", "CA1816", Justification = "GC.SuppressFinalize is called indirectly.")]
        public void Dispose()
        {
            if (Interlocked.CompareExchange(ref this.disposeStage, DisposalStarted, DisposalNotStarted) != DisposalNotStarted)
            {
                return;
            }

            this.OnDisposing();
            this.Disposing = null;

            this.Dispose(true);
            this.MarkAsDisposed();
        }

        /// &lt;summary&gt;
        /// Verifies that this object is not in the process of disposing, throwing an exception if it is.
        /// &lt;/summary&gt;
        protected void VerifyNotDisposing()
        {
            if (this.IsDisposing)
            {
                throw new ObjectDisposedException(this.ObjectName);
            }
        }

        /// &lt;summary&gt;
        /// Verifies that this object has not been disposed, throwing an exception if it is.
        /// &lt;/summary&gt;
        protected void VerifyNotDisposed()
        {
            if (this.IsDisposed)
            {
                throw new ObjectDisposedException(this.ObjectName);
            }
        }

        /// &lt;summary&gt;
        /// Verifies that this object is not being disposed or has been disposed, throwing an exception if either of these are true.
        /// &lt;/summary&gt;
        protected void VerifyNotDisposedOrDisposing()
        {
            if (this.IsDisposedOrDisposing)
            {
                throw new ObjectDisposedException(this.ObjectName);
            }
        }

        /// &lt;summary&gt;
        /// Allows subclasses to provide dispose logic.
        /// &lt;/summary&gt;
        /// &lt;param name="disposing"&gt;
        /// Whether the method is being called in response to disposal, or finalization.
        /// &lt;/param&gt;
        protected virtual void Dispose(bool disposing)
        {
        }

        /// &lt;summary&gt;
        /// Raises the &lt;see cref="Disposing"/&gt; event.
        /// &lt;/summary&gt;
        protected virtual void OnDisposing()
        {
            this.Disposing.Raise(this);
        }

        /// &lt;summary&gt;
        /// Marks this object as disposed without running any other dispose logic.
        /// &lt;/summary&gt;
        /// &lt;remarks&gt;
        /// Use this method with caution. It is helpful when you have an object that can be disposed in multiple fashions, such as through a &lt;c&gt;CloseAsync&lt;/c&gt; method.
        /// &lt;/remarks&gt;
        [SuppressMessage("Microsoft.Usage", "CA1816", Justification = "This is a helper method for IDisposable.Dispose.")]
        protected void MarkAsDisposed()
        {
            GC.SuppressFinalize(this);
            Interlocked.Exchange(ref this.disposeStage, DisposalComplete);
        }
    }
}

#endregion Designer generated code
#pragma warning restore 1591, 0612