Beispiel #1
0
 private void ReleaseNoLock(string lockName)
 {
     try
     {
         SqlApplicationLock.ExecuteReleaseCommand(this.connection, lockName);
     }
     finally
     {
         this.outstandingHandles.Remove(lockName);
         this.CloseConnectionIfNeededNoLock();
     }
 }
Beispiel #2
0
        static void Main(string[] args)
        {
            var locker = new SqlApplicationLock("MyAceApplication",
                                                "Server=xxx;Database=scratch;User Id=xx;Password=xxx;");

            Console.WriteLine("Aquiring the lock");
            using (locker.TakeLock(TimeSpan.FromMinutes(2)))
            {
                Console.WriteLine("Lock Aquired, doing work which no one else can do. Press any key to release the lock.");
                Console.ReadKey();
            }
            Console.WriteLine("Lock Released");
        }
Beispiel #3
0
        public async Task <Result> TryAcquireAsync(
            string lockName,
            int timeoutMillis,
            SqlApplicationLock.Mode mode,
            CancellationToken cancellationToken,
            bool opportunistic)
        {
            if (!await this.mutex.WaitAsync(opportunistic ? TimeSpan.Zero : Timeout.InfiniteTimeSpan, cancellationToken).ConfigureAwait(false))
            {
                // mutex wasn't free, so just give up
                return(this.GetFailureResultNoLock(Reason.MutexTimeout, opportunistic, timeoutMillis));
            }
            try
            {
                if (this.outstandingHandles.ContainsKey(lockName))
                {
                    // we won't try to hold the same lock twice on one connection. At some point, we could
                    // support this case in-memory using a counter for each multiply-held lock name and being careful
                    // with modes
                    return(this.GetFailureResultNoLock(Reason.AlreadyHeld, opportunistic, timeoutMillis));
                }

                if (this.connection.State != ConnectionState.Open)
                {
                    await this.connection.OpenAsync(cancellationToken).ConfigureAwait(false);
                }

                if (await SqlApplicationLock.ExecuteAcquireCommandAsync(this.connection, lockName, opportunistic ? 0 : timeoutMillis, mode, cancellationToken).ConfigureAwait(false))
                {
                    var handle = new Handle(this, lockName);
                    this.outstandingHandles.Add(lockName, new WeakReference <Handle>(handle));
                    return(new Result(handle));
                }

                // we failed to acquire the lock, so we should retry if we were being opportunistic and artificially
                // shortened the timeout
                return(this.GetFailureResultNoLock(Reason.AcquireTimeout, opportunistic, timeoutMillis));
            }
            finally
            {
                this.CloseConnectionIfNeededNoLock();
                this.mutex.Release();
            }
        }
Beispiel #4
0
        public Result TryAcquire(
            string lockName,
            int timeoutMillis,
            SqlApplicationLock.Mode mode,
            bool opportunistic)
        {
            if (!this.mutex.Wait(opportunistic ? TimeSpan.Zero : Timeout.InfiniteTimeSpan))
            {
                // mutex wasn't free, so just give up
                return(this.GetFailureResultNoLock(Reason.MutexTimeout, opportunistic, timeoutMillis));
            }
            try
            {
                if (this.outstandingHandles.ContainsKey(lockName))
                {
                    // we won't try to hold the same lock twice on one connection. At some point, we could
                    // support this case in-memory using a counter for each multiply-held lock name and being careful
                    // with modes
                    return(this.GetFailureResultNoLock(Reason.AlreadyHeld, opportunistic, timeoutMillis));
                }

                if (this.connection.State != ConnectionState.Open)
                {
                    this.connection.Open();
                }

                if (SqlApplicationLock.ExecuteAcquireCommand(this.connection, lockName, opportunistic ? 0 : timeoutMillis, mode))
                {
                    var handle = new Handle(this, lockName);
                    this.outstandingHandles.Add(lockName, new WeakReference <Handle>(handle));
                    return(new Result(handle));
                }

                return(this.GetFailureResultNoLock(Reason.AcquireTimeout, opportunistic, timeoutMillis));
            }
            finally
            {
                this.CloseConnectionIfNeededNoLock();
                this.mutex.Release();
            }
        }
Beispiel #5
0
        public async Task <bool> CleanupAsync()
        {
            await this.mutex.WaitAsync().ConfigureAwait(false);

            try
            {
                List <string> toRemove = null;
                foreach (var kvp in this.outstandingHandles)
                {
                    Handle ignored;
                    if (!kvp.Value.TryGetTarget(out ignored))
                    {
                        (toRemove ?? (toRemove = new List <string>())).Add(kvp.Key);
                    }
                }

                if (toRemove != null)
                {
                    foreach (var lockName in toRemove)
                    {
                        try { await SqlApplicationLock.ExecuteReleaseCommandAsync(this.connection, lockName).ConfigureAwait(false); }
                        catch
                        {
                            // suppress exceptions. If this fails there's not much else we can do
                        }
                        this.outstandingHandles.Remove(lockName);
                    }
                }

                return(this.outstandingHandles.Count > 0);
            }
            finally
            {
                this.CloseConnectionIfNeededNoLock();
                this.mutex.Release();
            }
        }