This is a followup to a previous question.Considering:Interlocked.CompareExchange generates a memory barrier,Intended to be used with very fast operations (like generating anid),SpinWait starts sleeping in milliseconds after 10 or so spins (anddoes some other smart stuff),What are characteristics (pros & cons) of this code?public class SpinMutex{    const long Locked = 1;    const long Unlocked = 0;    long _locked;    public SpinMutex() { _locked = Unlocked; }    /*public*/    void Lock()    {        SpinWait.SpinUntil(() => Interlocked.CompareExchange(ref _locked, Locked, Unlocked) == Unlocked);    }    /*public*/    bool Lock(int millisecondsTimeout)    {        return SpinWait.SpinUntil(() => Interlocked.CompareExchange(ref _locked, Locked, Unlocked) == Unlocked, millisecondsTimeout);    }    /*public*/    bool Lock(TimeSpan timeout)    {        return SpinWait.SpinUntil(() => Interlocked.CompareExchange(ref _locked, Locked, Unlocked) == Unlocked, timeout);    }    /*public*/    void Unlock()    {        Interlocked.CompareExchange(ref _locked, Unlocked, Locked);    }    public IDisposable EnterScope()    {        return new Scope(this);    }    public IDisposable EnterScope(int millisecondsTimeout)    {        return new Scope(this, millisecondsTimeout);    }    class Scope : IDisposable    {        SpinMutex _spinMutex;        int _millisecondsTimeout;        bool _locked;        bool _shouldDispose;        internal Scope(SpinMutex spinMutex, int millisecondsTimeout = -1)        {            _spinMutex = spinMutex;            _millisecondsTimeout = millisecondsTimeout < -1 ? -1 : millisecondsTimeout;            _locked = false;            _shouldDispose = true;            try            {                if (_millisecondsTimeout < 0) _spinMutex.Lock();                else if (!_spinMutex.Lock(_millisecondsTimeout)) throw new TimeoutException();                else _locked = true;            }            catch            {                Dispose();                _shouldDispose = false;                throw;            }        }        public void Dispose()        {            if (!_shouldDispose) return;            if (_millisecondsTimeout < 0) _spinMutex.Unlock();            else if (_locked) _spinMutex.Unlock();        }    }}And would be used like this:static readonly SpinMutex MySpinMutex = new SpinMutex();static void Process1(){    using (MySpinMutex.EnterScope()) { /* ... */ }}static void Process2(){    using (MySpinMutex.EnterScope()) { /* ... */ }}Instances of SpinMutex can be accessed from different Threads/Tasks safely.
Lock Using Interlocked vs lock Statement (Monitor) (Followup)
c#;multithreading;thread safety;asynchronous