public void RefreshRenameSessionWithOptionsChanged(Option <bool> renameOption, bool newValue)
        {
            AssertIsForeground();
            VerifyNotDismissed();

            // Recompute the result only if the previous result was computed with a different flag
            if (_optionSet.GetOption(renameOption) != newValue)
            {
                _optionSet = _optionSet.WithChangedOption(renameOption, newValue);

                var cancellationToken = _cancellationTokenSource.Token;

                UpdateReferenceLocationsTask(ThreadingContext.JoinableTaskFactory.RunAsync(async() =>
                {
                    // Join prior work before proceeding, since it performs a required state update.
                    // https://github.com/dotnet/roslyn/pull/34254#discussion_r267024593
                    //
                    // The cancellation token is passed to the prior work when it starts, not when it's joined. This is
                    // the equivalent of TaskContinuationOptions.LazyCancellation.
                    await _allRenameLocationsTask.JoinAsync(CancellationToken.None).ConfigureAwait(false);
                    await TaskScheduler.Default;

                    return(await _renameInfo.FindRenameLocationsAsync(_optionSet, cancellationToken).ConfigureAwait(false));
                }));
            }
        }
Example #2
0
        public void RefreshRenameSessionWithOptionsChanged(SymbolRenameOptions newOptions)
        {
            if (_options == newOptions)
            {
                return;
            }

            _threadingContext.ThrowIfNotOnUIThread();
            VerifyNotDismissed();

            _options = newOptions;

            var cancellationToken = _cancellationTokenSource.Token;

            UpdateReferenceLocationsTask(_threadingContext.JoinableTaskFactory.RunAsync(async() =>
            {
                // Join prior work before proceeding, since it performs a required state update.
                // https://github.com/dotnet/roslyn/pull/34254#discussion_r267024593
                //
                // The cancellation token is passed to the prior work when it starts, not when it's joined. This is
                // the equivalent of TaskContinuationOptions.LazyCancellation.
                await _allRenameLocationsTask.JoinAsync(CancellationToken.None).ConfigureAwait(false);
                await TaskScheduler.Default;

                return(await _renameInfo.FindRenameLocationsAsync(_options, cancellationToken).ConfigureAwait(false));
            }));
        }
        public void IsMainThreadBlockedTrueWhenAsyncOnOtherThreadBecomesSyncOnMainThread()
        {
            var          nonBlockingStateObserved = new AsyncManualResetEvent();
            var          nowBlocking  = new AsyncManualResetEvent();
            JoinableTask joinableTask = null;

            Task.Run(delegate
            {
                joinableTask = this.Factory.RunAsync(async delegate
                {
                    Assert.False(this.Context.IsMainThreadBlocked());
                    nonBlockingStateObserved.Set();
                    await Task.Yield();
                    await nowBlocking;
                    Assert.True(this.Context.IsMainThreadBlocked());
                });
            }).Wait();

            this.Factory.Run(async delegate
            {
                await nonBlockingStateObserved;
                joinableTask.JoinAsync().Forget();
                nowBlocking.Set();
            });
        }
Example #4
0
        private void QueueApplyReplacements()
        {
            // If the replacement text is empty, we do not update the results of the conflict
            // resolution task. We instead wait for a non-empty identifier.
            if (this.ReplacementText == string.Empty)
            {
                return;
            }

            var cancellationToken    = _conflictResolutionTaskCancellationSource.Token;
            var asyncToken           = _asyncListener.BeginAsyncOperation(nameof(QueueApplyReplacements));
            var replacementOperation = ThreadingContext.JoinableTaskFactory.RunAsync(async() =>
            {
                var replacementInfo = await _conflictResolutionTask.JoinAsync(CancellationToken.None).ConfigureAwait(false);
                if (replacementInfo == null || cancellationToken.IsCancellationRequested)
                {
                    return;
                }

                // Switch to a background thread for expensive work
                await TaskScheduler.Default;
                var computedMergeResult = await ComputeMergeResultAsync(replacementInfo, cancellationToken);
                await ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(alwaysYield: true, cancellationToken);
                ApplyReplacements(computedMergeResult.replacementInfo, computedMergeResult.mergeResult, cancellationToken);
            });

            replacementOperation.Task.CompletesAsyncOperation(asyncToken);
        }
Example #5
0
            // unfortunately, IVsOperationProgressStatusService requires UI thread to let project system to proceed to next stages.
            // this method should only be used with either await or JTF.Run, it should be never used with Task.Wait otherwise, it can
            // deadlock
            //
            // This method also ensures the GlobalHubClientPackage package is loaded, since brokered services in Visual
            // Studio require this package to provide proxy interfaces for invoking out-of-process services.
            public async Task WaitUntilFullyLoadedAsync(CancellationToken cancellationToken)
            {
                using (
                    Logger.LogBlock(
                        FunctionId.PartialLoad_FullyLoaded,
                        KeyValueLogMessage.NoProperty,
                        cancellationToken
                        )
                    )
                {
                    var status = await GetProgressStageStatusAsync(cancellationToken)
                                 .ConfigureAwait(false);

                    if (status == null)
                    {
                        return;
                    }

                    var completionTask = status.WaitForCompletionAsync();
                    Logger.Log(
                        FunctionId.PartialLoad_FullyLoaded,
                        KeyValueLogMessage.Create(
                            LogType.Trace,
                            m => m["AlreadyFullyLoaded"] = completionTask.IsCompleted
                            )
                        );

                    // TODO: WaitForCompletionAsync should accept cancellation directly.
                    //       for now, use WithCancellation to indirectly add cancellation
                    await completionTask.WithCancellation(cancellationToken).ConfigureAwait(false);

                    await _loadHubClientPackage.JoinAsync(cancellationToken).ConfigureAwait(false);
                }
            }
        private void UpdateReferenceLocationsTask(JoinableTask <IInlineRenameLocationSet> findRenameLocationsTask)
        {
            AssertIsForeground();

            var asyncToken = _asyncListener.BeginAsyncOperation("UpdateReferencesTask");

            _allRenameLocationsTask = ThreadingContext.JoinableTaskFactory.RunAsync(async() =>
            {
                var inlineRenameLocations = await findRenameLocationsTask.JoinAsync().ConfigureAwaitRunInline();

                // It's unfortunate that _allRenameLocationsTask has a UI thread dependency (prevents continuations
                // from running prior to the completion of the UI operation), but the implementation does not currently
                // follow the originally-intended design.
                // https://github.com/dotnet/roslyn/issues/40890
                await ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(alwaysYield: true, _cancellationTokenSource.Token);

                RaiseSessionSpansUpdated(inlineRenameLocations.Locations.ToImmutableArray());

                return(inlineRenameLocations);
            });

            _allRenameLocationsTask.Task.CompletesAsyncOperation(asyncToken);

            UpdateConflictResolutionTask();
            QueueApplyReplacements();
        }
Example #7
0
        /// <summary>
        /// Joins a task while displaying a progress dialog. If the dialog is closed by the user
        /// the entire CancelableTask is canceled.
        /// </summary>
        void JoinWithProgressDialog(JoinableTask joinableTask)
        {
            taskContext.ThrowIfNotOnMainThread();

            // Kick off a task that will mark the dialog as complete after joinableTask completes.
            var dialogTask = taskContext.Factory.RunAsync(async() =>
            {
                await taskContext.Factory.SwitchToMainThreadAsync();
                try
                {
                    await joinableTask.JoinAsync();
                }
                finally
                {
                    progressDialog.Complete();
                }
            });

            // Display the dialog and block until it's closed. The dialog spins up its own message
            // pump, which allows tasks to continue executing continuations on the main thread
            // despite the fact that we're making a blocking call.
            // If dialogTask succeeds in marking the dialog as complete, it closes and ShowModal
            // returns true.
            // If the dialog is canceled by the user, it closes, ShowModal returns false, and we
            // cancel the task using the cancellation source.
            if (!progressDialog.ShowModal())
            {
                cancellationSource.Cancel();
            }

            dialogTask.Join();
        }
        async Task QueueRefreshAsync()
        {
            if (refreshJoinableTask != null)
            {
                await refreshJoinableTask.JoinAsync(); // make sure StartRefresh has completed
            }

            await(refreshJoinableTask = JoinableTaskFactory.RunAsync(RefreshAsync));
        }
        public async Task TestMethod1()
        {
            Thread.CurrentThread.Name = "Main1";
            _control = new RoslynCodeControl();
            await _f.InitializeAsync();

            var c = _control;

            c.JTF2       = _f.JTF2;
            c.SourceText = "";

            var w = new Window();

            _window   = w;
            w.Content = _control;

            JoinableTask jt1 = null;

            w.Loaded += (sender, args) =>
            {
                jt1 = c.JTF.RunAsync(DoInput1Async);
                var continueWith = jt1.JoinAsync().ContinueWith(async t =>
                {
                    if (c.IsFaulted)
                    {
                    }
                    await c.ShutdownAsync();

                    c.Dispatcher.InvokeShutdown();
                    c.SecondaryDispatcher.InvokeShutdown();
                }, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
            };

            try
            {
                w.Show();
            }
            catch (Exception ex)
            {
                _f.Debugfn(ex.ToString());
            }
            Dispatcher.Run();
            await jt1.JoinAsync();
        }
Example #10
0
            private async ValueTask <IVsOperationProgressStageStatusForSolutionLoad?> GetProgressStageStatusAsync(CancellationToken cancellationToken)
            {
                // Workaround for lack of fast path in JoinAsync; avoid calling when already completed
                // https://github.com/microsoft/vs-threading/pull/696
                if (_progressStageStatus.Task.IsCompleted)
                {
                    return(await _progressStageStatus.Task.ConfigureAwait(false));
                }

                return(await _progressStageStatus.JoinAsync(cancellationToken).ConfigureAwait(false));
            }
Example #11
0
        protected override void SettingsToPage()
        {
            ThreadHelper.JoinableTaskFactory.RunAsync(
                async() =>
            {
                await _populateBuildServerTypeTask.JoinAsync();

                await this.SwitchToMainThreadAsync();

                checkBoxEnableBuildServerIntegration.SetNullableChecked(CurrentSettings.BuildServer.EnableIntegration.Value);

                BuildServerType.SelectedItem = CurrentSettings.BuildServer.Type.Value ?? _noneItem.Text;
            });
        }
Example #12
0
        /// <summary>
        /// Try to join a task, with a timeout.
        /// </summary>
        /// <returns>
        /// True if the task ran to completion in the time allotted, false if the task is still
        /// running.
        /// </returns>
        bool TryJoin(JoinableTask joinableTask, TimeSpan timeout)
        {
            // Task.Delay is used instead of a CancellationToken because `Task.Delay(TimeSpan.Zero)`
            // always completes synchronously, whereas `new CancellationTokenSource(TimeSpan.Zero)`
            // may or may not be canceled by the time it returns.
            return(taskContext.Factory.Run(async() =>
            {
                var task = joinableTask.JoinAsync();
                if (await Task.WhenAny(Task.Delay(delay), task) == task)
                {
                    await task; // Propagate exceptions
                    return true;
                }

                return false;
            }));
        }
Example #13
0
        protected override void SettingsToPage()
        {
            ThreadHelper.JoinableTaskFactory.RunAsync(
                async() =>
            {
                Validates.NotNull(_populateBuildServerTypeTask);

                await _populateBuildServerTypeTask.JoinAsync();

                await this.SwitchToMainThreadAsync();

                IBuildServerSettings buildServerSettings = GetCurrentSettings()
                                                           .BuildServer();

                checkBoxEnableBuildServerIntegration.SetNullableChecked(buildServerSettings.EnableIntegration);
                checkBoxShowBuildResultPage.SetNullableChecked(buildServerSettings.ShowBuildResultPage);

                BuildServerType.SelectedItem = buildServerSettings.Type ?? _noneItem.Text;
            });
        }
Example #14
0
        private async Task ObserveBuildsAsync(DateTime?sinceDate, bool?running, IObserver <BuildInfo> observer, CancellationToken cancellationToken)
        {
            if (_apiClient == null)
            {
                observer.OnCompleted();
                return;
            }

            try
            {
                if (_buildDefinitions == null)
                {
                    _buildDefinitions = await _buildDefinitionsTask.JoinAsync();

                    if (_buildDefinitions == null)
                    {
                        observer.OnCompleted();
                        return;
                    }

                    CacheAzureDevOps = new CacheAzureDevOps {
                        Id = CacheKey, BuildDefinitions = _buildDefinitions
                    };
                }

                var builds = await _apiClient.QueryBuildsAsync(_buildDefinitions, sinceDate, running);

                foreach (var build in builds)
                {
                    observer.OnNext(CreateBuildInfo(build));
                }
            }
            catch (OperationCanceledException)
            {
                // Do nothing, the observer is already stopped
            }
            catch (Exception ex)
            {
                observer.OnError(ex);
            }
        }
Example #15
0
        private void UpdateReferenceLocationsTask()
        {
            _threadingContext.ThrowIfNotOnUIThread();

            var asyncToken = _asyncListener.BeginAsyncOperation("UpdateReferencesTask");

            var currentOptions             = _options;
            var currentRenameLocationsTask = _allRenameLocationsTask;
            var cancellationToken          = _cancellationTokenSource.Token;

            _allRenameLocationsTask = _threadingContext.JoinableTaskFactory.RunAsync(async() =>
            {
                // Join prior work before proceeding, since it performs a required state update.
                // https://github.com/dotnet/roslyn/pull/34254#discussion_r267024593
                if (currentRenameLocationsTask != null)
                {
                    await _allRenameLocationsTask.JoinAsync(cancellationToken).ConfigureAwait(false);
                }

                await TaskScheduler.Default;
                var inlineRenameLocations = await _renameInfo.FindRenameLocationsAsync(currentOptions, cancellationToken).ConfigureAwait(false);

                // It's unfortunate that _allRenameLocationsTask has a UI thread dependency (prevents continuations
                // from running prior to the completion of the UI operation), but the implementation does not currently
                // follow the originally-intended design.
                // https://github.com/dotnet/roslyn/issues/40890
                await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(alwaysYield: true, cancellationToken);

                RaiseSessionSpansUpdated(inlineRenameLocations.Locations.ToImmutableArray());

                return(inlineRenameLocations);
            });

            _allRenameLocationsTask.Task.CompletesAsyncOperation(asyncToken);

            UpdateConflictResolutionTask();
            QueueApplyReplacements();
        }
Example #16
0
        private async Task ObserveBuilds(DateTime?sinceDate, bool?running, IObserver <BuildInfo> observer, CancellationToken cancellationToken)
        {
            try
            {
                if (_buildDefinitionsTask == null)
                {
                    _buildDefinitionsTask = ThreadHelper.JoinableTaskFactory.RunAsync(() =>
                                                                                      _gitLabClient.Pipelines.GetAsync(ProjectName, _ => _.Scope = PipelineScope.All));
                }


                if (_buildDefinitions == null)
                {
                    _buildDefinitions = await _buildDefinitionsTask.JoinAsync();

                    if (_buildDefinitions == null)
                    {
                        observer.OnCompleted();
                        return;
                    }
                }

                if (_buildDefinitions == null)
                {
                    observer.OnCompleted();
                    return;
                }

                Func <Pipeline, bool> predicate = pipeline =>
                                                  running.HasValue && running.Value
                        ? pipeline.Status == PipelineStatus.Running
                        : pipeline.Status != PipelineStatus.Running;

                if (sinceDate.HasValue)
                {
                    predicate += pipeline => pipeline.CreatedAt >= sinceDate;
                }

                var builds = _buildDefinitions.Where(predicate);

                foreach (var pipeline in builds)
                {
                    var status = pipeline.Status == PipelineStatus.Running
                        ? BuildInfo.BuildStatus.InProgress
                        : ParseBuildStatus(pipeline.Status);
                    var buildInfo = new BuildInfo
                    {
                        Id             = pipeline.Id.ToString(),
                        StartDate      = pipeline.CreatedAt.Value,
                        Status         = status,
                        CommitHashList = new List <ObjectId>
                        {
                            ObjectId.Parse(pipeline.Sha)
                        },
                        Url         = pipeline.WebUrl.ToString(),
                        Description = $"#{pipeline.Id} {status:G}"
                    };

                    observer.OnNext(buildInfo);
                }

                _buildDefinitionsTask = null;
                observer.OnCompleted();
            }
            catch (OperationCanceledException)
            {
                // Do nothing, the observer is already stopped
            }
            catch (Exception e)
            {
                observer.OnError(e);
            }
        }
Example #17
0
 public Task <GitSubmoduleStatus> GetSubmoduleStatusAsync()
 {
     return(_submoduleStatus?.JoinAsync());
 }
Example #18
0
 public Task <IGitHubPaneViewModel> GetViewModelAsync() => viewModelTask.JoinAsync();