private void ReleaseNoLock(string lockName) { try { SqlApplicationLock.ExecuteReleaseCommand(this.connection, lockName); } finally { this.outstandingHandles.Remove(lockName); this.CloseConnectionIfNeededNoLock(); } }
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"); }
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(); } }
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(); } }
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(); } }