コード例 #1
0
        /// <summary>
        /// Attempts to acquire the lock synchronously. Usage:
        /// <code>
        ///     using (var handle = myLock.TryAcquire(...))
        ///     {
        ///         if (handle != null) { /* we have the lock! */ }
        ///     }
        ///     // dispose releases the lock if we took it
        /// </code>
        /// </summary>
        /// <param name="timeout">How long to wait before giving up on acquiring the lock. Defaults to 0</param>
        /// <param name="cancellationToken">Specifies a token by which the wait can be canceled</param>
        /// <returns>An <see cref="IDisposable"/> "handle" which can be used to release the lock, or null if the lock was not taken</returns>
        public IDisposable TryAcquire(TimeSpan timeout = default(TimeSpan), CancellationToken cancellationToken = default(CancellationToken))
        {
            if (cancellationToken.CanBeCanceled)
            {
                // use the async version since that supports cancellation
                return(DistributedLockHelpers.TryAcquireWithAsyncCancellation(this, timeout, cancellationToken));
            }

            // synchronous mode
            var timeoutMillis = timeout.ToInt32Timeout();

            DbConnection  connection  = null;
            DbTransaction transaction = null;
            var           cleanup     = true;

            try
            {
                connection = this.GetConnection();
                if (this.connectionString != null)
                {
                    connection.Open();
                }
                else if (connection == null)
                {
                    throw new InvalidOperationException("The transaction had been disposed");
                }
                else if (connection.State != ConnectionState.Open)
                {
                    throw new InvalidOperationException("The connection is not open");
                }

                transaction = this.GetTransaction(connection);
                SqlParameter returnValue;
                using (var command = CreateAcquireCommand(connection, transaction, this.lockName, timeoutMillis, out returnValue))
                {
                    command.ExecuteNonQuery();
                    var exitCode = (int)returnValue.Value;
                    if (ParseExitCode(exitCode))
                    {
                        cleanup = false;
                        return(new LockScope(this, transaction));
                    }
                    return(null);
                }
            }
            catch
            {
                // in case we fail to create lock scope or something
                cleanup = true;
                throw;
            }
            finally
            {
                if (cleanup)
                {
                    this.Cleanup(transaction, connection);
                }
            }
        }
コード例 #2
0
 /// <summary>
 /// Attempts to acquire the lock synchronously. Usage:
 /// <code>
 ///     using (var handle = myLock.TryAcquire(...))
 ///     {
 ///         if (handle != null) { /* we have the lock! */ }
 ///     }
 ///     // dispose releases the lock if we took it
 /// </code>
 /// </summary>
 /// <param name="timeout">How long to wait before giving up on acquiring the lock. Defaults to 0</param>
 /// <param name="cancellationToken">Specifies a token by which the wait can be canceled</param>
 /// <returns>An <see cref="IDisposable"/> "handle" which can be used to release the lock, or null if the lock was not taken</returns>
 public IDisposable TryAcquire(TimeSpan timeout = default(TimeSpan), CancellationToken cancellationToken = default(CancellationToken))
 {
     return(cancellationToken.CanBeCanceled
            // use the async version since that supports cancellation
         ? DistributedLockHelpers.TryAcquireWithAsyncCancellation(this, timeout, cancellationToken)
            // synchronous mode
         : this.internalLock.TryAcquire(timeout.ToInt32Timeout(), SqlApplicationLock.Mode.Exclusive, contextHandle: null));
 }