public async Task WaitSignaledAsync_should_not_continue_on_signal_thread()
        {
            var cancelationTokenSource = new CancellationTokenSource();

            var semaphore        = new SemaphoreSlimSignalable(0);
            var waitStartedEvent = new ManualResetEventSlim(false);

            var signalThreadTerminated = false;
            var signalThread           = SignalThread();

            for (int i = 0; i < 100; i++)
            {
                semaphore.Reset();
                waitStartedEvent.Reset();

                var   waitSignaledTask = WaitSignaledTask();
                await waitSignaledTask;

                waitSignaledTask.Result.Should().NotBe(signalThread.ManagedThreadId);
            }

            Volatile.Write(ref signalThreadTerminated, true);
            waitStartedEvent.Set();
            signalThread.Join(100);

            async Task <int> WaitSignaledTask()
            {
                await Task.Yield();

                var waitTask = semaphore.WaitSignaledAsync(Timeout.InfiniteTimeSpan, cancelationTokenSource.Token);

                waitStartedEvent.Set();

                var waitResult = await waitTask;

                waitResult.Should().Be(SemaphoreSlimSignalable.SemaphoreWaitResult.Signaled);

                return(Thread.CurrentThread.ManagedThreadId);
            }

            Thread SignalThread()
            {
                var thread = new Thread(_ =>
                {
                    while (!Volatile.Read(ref signalThreadTerminated))
                    {
                        waitStartedEvent.Wait();
                        waitStartedEvent.Reset();

                        semaphore.Signal();
                    }
                });

                thread.IsBackground = true;
                thread.Start();

                return(thread);
            }
        }
예제 #2
0
        public async Task SemaphoreSlimSignalable_wait_should_signal(
            [Values(true, false)] bool async,
            [Values(true, false)] bool signalBeforeWait)
        {
            const int threadsCount = 4;
            var       semaphore    = new SemaphoreSlimSignalable(0);

            if (signalBeforeWait)
            {
                semaphore.Signal();
            }
            var waitTask = WaitAsync(semaphore, async, true, threadsCount, Timeout.InfiniteTimeSpan);

            if (!signalBeforeWait)
            {
                semaphore.Signal();
            }

            var results = await waitTask;

            Assert(results, SemaphoreSlimSignalable.SemaphoreWaitResult.Signaled);
        }
        public async Task Reset_should_not_reset_non_signaled(
            [Values(true, false)] bool async)
        {
            const int threadsCount = 4;
            var       semaphore    = new SemaphoreSlimSignalable(0);

            var waitTasks = WaitAsync(semaphore, async, true, threadsCount, TimeSpan.FromSeconds(5));

            semaphore.Reset();
            semaphore.Signal();

            var results = await waitTasks;

            Assert(results, SemaphoreSlimSignalable.SemaphoreWaitResult.Signaled);
        }
        public async Task Reset_should_clear_signal(
            [Values(true, false)] bool async)
        {
            const int threadsCount = 4;
            var       semaphore    = new SemaphoreSlimSignalable(0);

            semaphore.Signal();
            semaphore.Reset();

            var waitTasks = WaitAsync(semaphore, async, true, threadsCount, TimeSpan.FromSeconds(5));

            for (int i = 0; i < threadsCount; i++)
            {
                semaphore.Release();
            }

            var results = await waitTasks;

            Assert(results, SemaphoreSlimSignalable.SemaphoreWaitResult.Entered);
        }