public void Release()
 {
     if (Interlocked.CompareExchange(ref _isReleased, 1, 0) == 1)
     {
         throw new LockTokenWasAlreadyReleasedException();
     }
     _holder.ReleaseLock(this, _matrix);
 }
        /// <summary>
        /// Obtains an exclusive lock according to the specified <see cref="LockToken" />,
        /// then executes the specified <see cref="Action" /> before releasing the lock.
        /// </summary>
        /// <param name="token">The token dictating the scope and behavior of execution.</param>
        /// <param name="action">The action to execute.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="token" /> is null.
        /// <para>or</para>
        /// <paramref name="action" /> is null.
        /// </exception>
        /// <exception cref="AcquireLockTimeoutException">The lock could not be obtained within the acquisition timeout specified by <paramref name="token" />.</exception>
        /// <exception cref="HoldLockTimeoutException"><paramref name="action" /> did not complete within the hold timeout specified by <paramref name="token" />.</exception>
        public void Run(LockToken token, Action action)
        {
            if (token == null)
            {
                throw new ArgumentNullException(nameof(token));
            }

            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            LockTicket lockTicket = _lockManager.AcquireLock(token.Key, token.AcquireTimeout, 1, _requestName);

            try
            {
                RunAction(token, action);
            }
            finally
            {
                _lockManager.ReleaseLock(lockTicket);
            }
        }