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); } }
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));