private void ReleaseLockInternal(LockArgs lockArgs, LockContext context, CloudBlockBlob blob, string leaseId) { context.AutoRenew = false; var releaseTask = new Task(() => { blob.ReleaseLease(new AccessCondition() { LeaseId = leaseId }); if (LockReleased != null) LockReleased(lockArgs); }); if (LockReleaseMode == AzureStorage.LockReleaseMode.Asyncronous) { releaseTask.Start(); } else if (LockReleaseMode == AzureStorage.LockReleaseMode.Syncronous) { releaseTask.RunSynchronously(); } else if (LockReleaseMode == AzureStorage.LockReleaseMode.LetExpire) { // Do nothing } else { throw new NotImplementedException("There should not be a possibility for an else"); } }
private async Task LockInternal(string lockId, string requestId, Action<LockContext> body, int timeLimitInSeconds, DateTime? timeoutTime) { var lockArgs = new LockArgs(lockId, requestId, 1); if (timeLimitInSeconds > 0 && (timeLimitInSeconds < 16 || timeLimitInSeconds > 59)) { throw new ArgumentException("timeLimitInSeconds must be at least 16 and no greater than 59"); } CloudBlockBlob blob = container.GetBlockBlobReference(lockId); if (blob.Exists() == false) { MemoryStream ms = new MemoryStream(); blob.UploadFromStream(ms); } var lockContext = new LockContext(blob, null); bool gotLock = false; string leaseId = null; while (gotLock == false) { try { TimeSpan? maxLeaseTime = null; if (timeLimitInSeconds > 0) maxLeaseTime = TimeSpan.FromSeconds(timeLimitInSeconds); string proposedLeaseId = null; object state = null; leaseId = await Task<string>.Factory.FromAsync(blob.BeginAcquireLease, blob.EndAcquireLease, maxLeaseTime, proposedLeaseId, state, TaskCreationOptions.None); lockContext.LeaseId = leaseId; lockContext.AutoRenew = this.AutoRenew; lockContext.LockRenewed += (context) => { if (LockRenewed != null) LockRenewed(lockArgs); }; gotLock = true; if (maxLeaseTime.HasValue) { lockContext.LockWarningTimerDuration = maxLeaseTime.Value - ExpiryWarningThreshold; lockContext.LockWarningTimer = new Timer((o) => { if (LeaseNearExpiry != null) LeaseNearExpiry(lockArgs, lockContext); }, null, (int)lockContext.LockWarningTimerDuration.TotalMilliseconds, Timeout.Infinite); } if (LockAcquired != null) LockAcquired(lockArgs); body(new LockContext(blob,leaseId)); if(lockContext.LockWarningTimer != null) lockContext.LockWarningTimer.Dispose(); } catch (StorageException ex) { var innerWeb = ex.InnerException as WebException; if (innerWeb == null) throw; var response = innerWeb.Response as HttpWebResponse; if (response == null) throw; if (response.StatusCode != HttpStatusCode.Conflict) throw; if (timeoutTime.HasValue && DateTime.UtcNow > timeoutTime.Value) { throw GetTimeoutExceptionInternal(); }; } finally { if(gotLock) ReleaseLockInternal(lockArgs, lockContext, blob, leaseId); } if (gotLock == false) { if (LockWaiting != null) LockWaiting(lockArgs); lockArgs.AttemptNumber++; await Task.Delay(PollingInterval); } } }