public async Task IsEncapsulated() { using var s1 = new SemaphoreWrapper(1); using var s2 = new SemaphoreWrapper(1); await s1.EnterQueue().OrTimeout(); await s2.EnterQueue().OrTimeout(); }
public async Task WaitsIfNoSpaceAvailible() { using var s = new SemaphoreWrapper(1); await s.EnterQueue().OrTimeout(); var waitingTask = s.EnterQueue(); Assert.False(waitingTask.IsCompleted); s.LeaveQueue(); await waitingTask.OrTimeout(); }
public async Task TracksQueueLength() { using var s = new SemaphoreWrapper(1); Assert.Equal(1, s.Count); await s.EnterQueue().OrTimeout(); Assert.Equal(0, s.Count); s.LeaveQueue(); Assert.Equal(1, s.Count); }
private void Release(SemaphoreWrapper wrapper) { lock (_lock) { var isEmpty = wrapper.Release(); if (!isEmpty) { return; } _wrapperMap.Remove(wrapper.Key); } }
public void DoesNotWaitIfSpaceAvailible() { using var s = new SemaphoreWrapper(2); var t1 = s.EnterQueue(); Assert.True(t1.IsCompleted); var t2 = s.EnterQueue(); Assert.True(t2.IsCompleted); var t3 = s.EnterQueue(); Assert.False(t3.IsCompleted); }
public Task <IDisposable> WaitAsync( string key, CancellationToken cancelToken = default(CancellationToken)) { lock (_lock) { SemaphoreWrapper wrapper; if (_wrapperMap.ContainsKey(key)) { wrapper = _wrapperMap[key]; } else { wrapper = _wrapperMap[key] = new SemaphoreWrapper(Release); wrapper.Key = key; } return(wrapper.WaitAsync(cancelToken)); } }
public async static Task <T> ExecuteWithFileLocked <T>(string filePath, Func <bool, Task <T> > action) { bool completed = false; while (!completed) { var createdNew = false; using (var fileLock = SemaphoreWrapper.Create(initialCount: 0, maximumCount: 1, name: FilePathToLockName(filePath), createdNew: out createdNew)) { try { // If this lock is already acquired by another process, wait until we can acquire it if (!createdNew) { var signaled = fileLock.WaitOne(TimeSpan.FromSeconds(5)); if (!signaled) { // Timeout and retry continue; } } completed = true; return(await action(createdNew)); } finally { if (completed) { fileLock.Release(); } } } } // should never get here throw new TaskCanceledException($"Failed to acquire semaphore for file: {filePath}"); }