Пример #1
0
        public async Task IsEncapsulated()
        {
            using var s1 = new SemaphoreWrapper(1);
            using var s2 = new SemaphoreWrapper(1);

            await s1.EnterQueue().OrTimeout();

            await s2.EnterQueue().OrTimeout();
        }
Пример #2
0
        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();
        }
Пример #3
0
        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);
        }
Пример #4
0
        private void Release(SemaphoreWrapper wrapper)
        {
            lock (_lock)
            {
                var isEmpty = wrapper.Release();
                if (!isEmpty)
                {
                    return;
                }

                _wrapperMap.Remove(wrapper.Key);
            }
        }
Пример #5
0
        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);
        }
Пример #6
0
        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));
            }
        }
Пример #7
0
        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}");
        }