public async Task <bool> WaitSignaledAsync(TimeSpan timeout, CancellationToken cancellationToken)
            {
                var waitResult = await _semaphoreSlimSignalable.WaitSignaledAsync(timeout, cancellationToken).ConfigureAwait(false);

                _enteredSemaphore = waitResult == SemaphoreWaitResult.Entered;
                return(_enteredSemaphore);
            }
        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);
            }
        }
Пример #3
0
 private Task <SemaphoreSlimSignalable.SemaphoreWaitResult>[] CreateWaitTasks(
     SemaphoreSlimSignalable semaphore,
     bool async,
     bool isSignaledWait,
     int threadsCount,
     TimeSpan timeout,
     CancellationToken cancellationToken = default) =>
 async?
 TasksUtils.CreateTasks(threadsCount, _ => isSignaledWait?semaphore.WaitSignaledAsync(timeout, cancellationToken) : semaphore.WaitAsync(timeout, cancellationToken)) :
     TasksUtils.CreateTasksOnOwnThread(threadsCount, _ => isSignaledWait ? semaphore.WaitSignaled(timeout, cancellationToken) : semaphore.Wait(timeout, cancellationToken));