Beispiel #1
0
        private void ProgressUpdated()
        {
            // we prefer showing evaluating if progress is flipping between evaluate and pause
            // in short period of time.
            var forceUpdate = _lastShownProgressStatus == ProgressStatus.Paused &&
                              _lastProgressStatus == ProgressStatus.Evaluating;

            var current = DateTimeOffset.UtcNow;

            if (!forceUpdate && current - _lastTimeReported < s_minimumInterval)
            {
                // make sure we are not flooding UI.
                // this is just presentation, fine to not updating UI right away especially since
                // at the end, this notification will go away automatically
                // but to make UI to be updated to right status eventually if task takes long time to finish
                // we enqueue refresh task.
                EnqueueRefresh();
                return;
            }

            _lastShownProgressStatus = _lastProgressStatus;
            _lastTimeReported        = current;

            ChangeProgress(_taskHandler, GetMessage());

            string GetMessage()
            {
                var statusMessage = (_lastProgressStatus == ProgressStatus.Paused) ? ServicesVSResources.Paused_0_tasks_in_queue : ServicesVSResources.Evaluating_0_tasks_in_queue;

                return(string.Format(statusMessage, _lastPendingItemCount));
            }

            void EnqueueRefresh()
            {
                if (_resettableDelay != null)
                {
                    _resettableDelay.Reset();
                    return;
                }

                _resettableDelay = new ResettableDelay((int)s_minimumInterval.TotalMilliseconds, AsynchronousOperationListenerProvider.NullListener);
                _resettableDelay.Task.SafeContinueWith(_ =>
                {
                    _resettableDelay = null;
                    ProgressUpdated();
                }, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
            }
        }
Beispiel #2
0
            private void OnWorkspaceChanged(object sender, WorkspaceChangeEventArgs e)
            {
                // workspace event is serialized events. and reset delay only get updated here
                if (!_resettableDelay.Task.IsCompleted)
                {
                    _resettableDelay.Reset();
                    return;
                }

                var delay = new ResettableDelay((int)s_delay.TotalMilliseconds, expeditableDelaySource: AsynchronousOperationListenerProvider.NullListener);

                _resettableDelay = delay;
                delay.Task.ContinueWith(InvalidateAsync, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);

                async Task InvalidateAsync(Task _)
                {
                    var document = _workspace.CurrentSolution.GetDocument(_documentId);

                    if (document == null)
                    {
                        return;
                    }

                    var newVersion = await document.Project.GetDependentVersionAsync(CancellationToken.None).ConfigureAwait(false);

                    if (newVersion == _lastVersion)
                    {
                        return;
                    }

                    // fire and forget.
                    // ignore any exception such as rpc already disposed (disconnected)

                    _lastVersion = newVersion;

                    await _endPoint.InvokeAsync(
                        nameof(IRemoteCodeLensDataPoint.Invalidate),
                        Array.Empty <object>(),
                        CancellationToken.None).ConfigureAwait(false);
                }
            }
Beispiel #3
0
            public Task <bool> IsFullyLoadedAsync(CancellationToken cancellationToken)
            {
                if (_workspace.Options.GetOption(ExperimentationOptions.SolutionStatusService_ForceDelay))
                {
                    // this is for prototype/mock for people/teams trying partial solution load prototyping
                    // it shouldn't concern anyone outside of that group.
                    //
                    // "experimentationService.IsExperimentEnabled(WellKnownExperimentNames.PartialLoadMode)" check above
                    // make sure this part of code "Service : IWorkspaceStatusService" is not exposed anyone outside of
                    // the partial solution load group.
                    //
                    // for ones that is in the group, one can try lightbulb behavior through internal option page
                    // such as moving around caret on lines where LB should show up.
                    //
                    // it works as below
                    // 1. when this is first called, we return false and start timer to change its status in delayInMS
                    // 2. once delayInMs passed, we clear the delay and return true.
                    // 3. if it is called before the timeout, we reset the timer and return false
                    if (_lastTimeCalled == null)
                    {
                        var delay = _workspace.Options.GetOption(ExperimentationOptions.SolutionStatusService_DelayInMS);
                        _lastTimeCalled = new ResettableDelay(delayInMilliseconds: delay, AsynchronousOperationListenerProvider.NullListener);
                        _ = _lastTimeCalled.Task.SafeContinueWith(_ => StatusChanged?.Invoke(this, true), TaskScheduler.Default);

                        return(SpecializedTasks.False);
                    }

                    if (_lastTimeCalled.Task.IsCompleted)
                    {
                        _lastTimeCalled = null;
                        return(SpecializedTasks.True);
                    }

                    _lastTimeCalled.Reset();
                    return(SpecializedTasks.False);
                }

                // we are using this API for now, until platform provide us new API for prototype
                return(KnownUIContexts.SolutionExistsAndFullyLoadedContext.IsActive ? SpecializedTasks.True : SpecializedTasks.False);
            }