public Task GetValueAsync()

in src/Microsoft.VisualStudio.Threading/AsyncLazy`1.cs [111:192]


        public Task<T> GetValueAsync(CancellationToken cancellationToken)
        {
            if (!((this.value is object && this.value.IsCompleted) || this.recursiveFactoryCheck.Value is null))
            {
                // PERF: we check the condition and *then* retrieve the string resource only on failure
                // because the string retrieval has shown up as significant on ETL traces.
                Verify.FailOperation(Strings.ValueFactoryReentrancy);
            }

            if (this.value is null)
            {
                if (Monitor.IsEntered(this.syncObject))
                {
                    // PERF: we check the condition and *then* retrieve the string resource only on failure
                    // because the string retrieval has shown up as significant on ETL traces.
                    Verify.FailOperation(Strings.ValueFactoryReentrancy);
                }

                InlineResumable? resumableAwaiter = null;
                lock (this.syncObject)
                {
                    // Note that if multiple threads hit GetValueAsync() before
                    // the valueFactory has completed its synchronous execution,
                    // then only one thread will execute the valueFactory while the
                    // other threads synchronously block till the synchronous portion
                    // has completed.
                    if (this.value is null)
                    {
                        RoslynDebug.Assert(this.valueFactory is object);

                        cancellationToken.ThrowIfCancellationRequested();
                        resumableAwaiter = new InlineResumable();
                        Func<Task<T>>? originalValueFactory = this.valueFactory;
                        this.valueFactory = null;
                        Func<Task<T>> valueFactory = async delegate
                        {
                            try
                            {
                                await resumableAwaiter;
                                return await originalValueFactory().ConfigureAwaitRunInline();
                            }
                            finally
                            {
                                this.jobFactory = null;
                                this.joinableTask = null;
                            }
                        };

                        this.recursiveFactoryCheck.Value = RecursiveCheckSentinel;
                        try
                        {
                            if (this.jobFactory is object)
                            {
                                // Wrapping with RunAsync allows a future caller
                                // to synchronously block the Main thread waiting for the result
                                // without leading to deadlocks.
                                this.joinableTask = this.jobFactory.RunAsync(valueFactory);
                                this.value = this.joinableTask.Task;
                            }
                            else
                            {
                                this.value = valueFactory();
                            }
                        }
                        finally
                        {
                            this.recursiveFactoryCheck.Value = null;
                        }
                    }
                }

                // Allow the original value factory to actually run.
                resumableAwaiter?.Resume();
            }

            if (!this.value.IsCompleted)
            {
                this.joinableTask?.JoinAsync(cancellationToken).Forget();
            }

            return this.value.WithCancellation(cancellationToken);
        }