public override async Task ExecuteAsync()

in src/Microsoft.VisualStudio.Threading/ReentrantSemaphore.cs [931:1021]


            public override async Task ExecuteAsync(Func<Task> operation, CancellationToken cancellationToken = default)
            {
                Requires.NotNull(operation, nameof(operation));
                this.ThrowIfFaulted();

                // No race condition here: We're accessing AsyncLocal<T> which we by definition have our own copy of.
                // Multiple threads or multiple async methods will all have their own storage for this field.
                Stack<AsyncSemaphore.Releaser>? reentrantStack = this.reentrantCount.Value;
                if (reentrantStack is null || reentrantStack.Count == 0)
                {
                    this.reentrantCount.Value = reentrantStack = new Stack<AsyncSemaphore.Releaser>(capacity: 2);
                }

                // Note: this code is duplicated and not extracted to minimize allocating extra async state machines.
                // For performance reasons in the JTF enabled scenario, we want to minimize the number of Joins performed, and also
                // keep the size of the JoinableCollection to a minimum. This also means awaiting on the semaphore outside of a
                // JTF.RunAsync. This requires us to not ConfigureAwait(true) on the semaphore. However, that prevents us from
                // resuming on the correct sync context. To partially fix this, we will at least resume you on the main thread or
                // thread pool.
                AsyncSemaphore.Releaser releaser = default;
                bool pushed = false;
                try
                {
                    bool resumeOnMainThread = this.IsJoinableTaskAware(out _, out JoinableTaskCollection? joinableTaskCollection)
                        ? joinableTaskCollection.Context.IsOnMainThread
                        : false;
                    bool mustYield = false;
                    if (reentrantStack.Count == 0)
                    {
                        using (this.joinableTaskCollection?.Join())
                        {
                            if (this.IsJoinableTaskAware(out _, out _))
                            {
                                // Use ConfiguredAwaitRunInline() as ConfigureAwait(true) will
                                // deadlock due to not being inside a JTF.RunAsync().
                                Task<AsyncSemaphore.Releaser>? releaserTask = this.semaphore.EnterAsync(cancellationToken);

                                // Yield to prevent running on the stack that released the semaphore.
                                mustYield = !releaserTask.IsCompleted;

                                releaser = await releaserTask.ConfigureAwaitRunInline();
                            }
                            else
                            {
                                releaser = await this.semaphore.EnterAsync(cancellationToken).ConfigureAwait(true);
                            }
                        }
                    }
                    else
                    {
                        releaser = default;
                    }

                    await this.ExecuteCoreAsync(async delegate
                    {
                        if (this.IsJoinableTaskAware(out JoinableTaskFactory? joinableTaskFactory, out _))
                        {
                            if (resumeOnMainThread)
                            {
                                // Return to the main thread if we started there.
                                await joinableTaskFactory.SwitchToMainThreadAsync(alwaysYield: mustYield, cancellationToken);
                            }
                            else
                            {
                                await TaskScheduler.Default.SwitchTo(alwaysYield: mustYield);
                            }
                        }

                        lock (reentrantStack)
                        {
                            reentrantStack.Push(releaser);
                            pushed = true;
                            releaser = default; // we should release whatever we pop off the stack (which ensures the last surviving nested holder actually releases).
                        }

                        await operation().ConfigureAwaitRunInline();
                    });
                }
                finally
                {
                    if (pushed)
                    {
                        lock (reentrantStack)
                        {
                            releaser = reentrantStack.Pop();
                        }
                    }

                    DisposeReleaserNoThrow(releaser);
                }
            }