Exemple #1
0
        private void UpdateConflictResolutionTask()
        {
            AssertIsForeground();

            _conflictResolutionTaskCancellationSource.Cancel();
            _conflictResolutionTaskCancellationSource = new CancellationTokenSource();

            // 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 replacementText   = this.ReplacementText;
            var optionSet         = _optionSet;
            var cancellationToken = _conflictResolutionTaskCancellationSource.Token;

            var asyncToken = _asyncListener.BeginAsyncOperation(nameof(UpdateConflictResolutionTask));

            _conflictResolutionTask = 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 cancellation of the conflict resolution task is requested before the rename locations task
                // completes, we do not need to wait for rename before cancelling. The next conflict resolution task
                // will wait on the latest rename location task if/when necessary.
                var result = await _allRenameLocationsTask.JoinAsync(cancellationToken).ConfigureAwait(false);
                await TaskScheduler.Default;

                return(await result.GetReplacementsAsync(replacementText, optionSet, cancellationToken).ConfigureAwait(false));
            });

            _conflictResolutionTask.Task.CompletesAsyncOperation(asyncToken);
        }
Exemple #2
0
        public override void StopListening()
        {
            _foregroundDispatcher.AssertForegroundThread();

            if (_fileChangeAdviseTask == null || _fileChangeUnadviseTask?.IsCompleted == false)
            {
                // Already not listening or trying to stop listening
                return;
            }

            _fileChangeUnadviseTask = _joinableTaskFactory.RunAsync(async() =>
            {
                try
                {
                    var fileChangeCookie = await _fileChangeAdviseTask;

                    if (fileChangeCookie == VSConstants.VSCOOKIE_NIL)
                    {
                        // Wasn't able to listen for file change events. This typically happens when some sort of exception (i.e. access exceptions)
                        // is thrown when attempting to listen for file changes.
                        return;
                    }

                    await _fileChangeService.UnadviseFileChangeAsync(fileChangeCookie);
                    _fileChangeAdviseTask = null;
                }
                catch (PathTooLongException)
                {
                    // Don't report PathTooLongExceptions but don't fault either.
                }
                catch (Exception exception)
                {
                    _errorReporter.ReportError(exception);
                }
            });
        }
 protected override void OnTransitionedToMainThread(JoinableTask joinableTask, bool canceled)
 {
     base.OnTransitionedToMainThread(joinableTask, canceled);
     this.OnTransitionedToMainThreadCallback?.Invoke(joinableTask, canceled);
 }
 protected override void OnTransitioningToMainThread(JoinableTask joinableTask)
 {
     base.OnTransitioningToMainThread(joinableTask);
     this.OnTransitioningToMainThreadCallback?.Invoke(joinableTask);
 }
Exemple #5
0
        /// <summary>
        /// Adds the given AggregateConfiguration, CohortAggregateContainer or JoinableCohortAggregateConfiguration to the compiler Task list or returns the existing
        /// ICompileable if it is already part of the Compilation list.  This will not start the task, you will have to call Launch... to start the ICompileable executing
        /// </summary>
        /// <param name="runnable">An AggregateConfiguration, CohortAggregateContainer or JoinableCohortAggregateConfiguration you want to schedule for execution</param>
        /// <param name="globals"></param>
        /// <returns></returns>
        public ICompileable AddTask(IMapsDirectlyToDatabaseTable runnable, IEnumerable <ISqlParameter> globals)
        {
            var aggregate = runnable as AggregateConfiguration;
            var container = runnable as CohortAggregateContainer;
            var joinable  = runnable as JoinableCohortAggregateConfiguration;


            if (aggregate == null && container == null && joinable == null)
            {
                throw new NotSupportedException(
                          "Expected c to be either AggregateConfiguration or CohortAggregateContainer but it was " +
                          runnable.GetType().Name);
            }

            CancellationTokenSource source = new CancellationTokenSource();
            ICompileable            task;

            //thing that will produce the SQL
            CohortQueryBuilder       queryBuilder;
            CohortQueryBuilder       cumulativeQueryBuilder = null;
            CohortAggregateContainer parent;

            //if it is an aggregate
            if (aggregate != null)
            {
                //which has a parent
                task         = new AggregationTask(aggregate, this);
                queryBuilder = new CohortQueryBuilder(aggregate, globals);

                parent = aggregate.GetCohortAggregateContainerIfAny();
            }
            else if (joinable != null)
            {
                task         = new JoinableTask(joinable, this);
                queryBuilder = new CohortQueryBuilder(joinable.AggregateConfiguration, globals, true);
                parent       = null;
            }
            else
            {
                task         = new AggregationContainerTask(container, this);
                queryBuilder = new CohortQueryBuilder(container, globals);
                parent       = container.GetParentContainerIfAny();
            }

            //if there is a parent
            if (parent != null)
            {
                //tell the task what the container is for UI purposes really
                bool isFirstInContainer = parent.GetOrderedContents().First().Equals(runnable);
                task.SetKnownContainer(parent, isFirstInContainer);

                //but...
                //if the container/aggregate being processed isn't the first component in the container
                if (!isFirstInContainer && IncludeCumulativeTotals) //and we want cumulative totals
                {
                    cumulativeQueryBuilder = new CohortQueryBuilder(parent, globals);
                    cumulativeQueryBuilder.StopContainerWhenYouReach = (IOrderable)runnable;
                }
            }
            ExternalDatabaseServer cacheServer = null;

            //if the overall owner has a cache configured
            if (CohortIdentificationConfiguration.QueryCachingServer_ID != null)
            {
                cacheServer = CohortIdentificationConfiguration.QueryCachingServer;
                queryBuilder.CacheServer = cacheServer;

                if (cumulativeQueryBuilder != null)
                {
                    cumulativeQueryBuilder.CacheServer = cacheServer;
                }
            }

            //setup cancellation
            task.CancellationToken = source.Token;
            string newsql        = "";
            string cumulativeSql = "";

            try
            {
                //get the count(*) SQL
                newsql = queryBuilder.SQL;

                if (cumulativeQueryBuilder != null)
                {
                    cumulativeSql = cumulativeQueryBuilder.SQL;
                }
            }
            catch (QueryBuildingException e)
            {
                //it was not possible to generate valid SQL for the task
                task.CrashMessage = e;
                task.State        = CompilationState.Crashed;
            }

            //we have seen this entity before (by ID & entity type)
            KeyValuePair <ICompileable, CohortIdentificationTaskExecution> existingTask;

            if (joinable != null)
            {
                existingTask = Tasks.SingleOrDefault((kvp => kvp.Key.Child.Equals(joinable)));
            }
            else
            if (aggregate != null)
            {
                existingTask = Tasks.SingleOrDefault(kvp => kvp.Key.Child.Equals(aggregate));
            }
            else
            {
                existingTask = Tasks.SingleOrDefault(kvp => kvp.Key.Child.Equals(container));
            }


            //job already exists (this is the same as saying existingTask!=null)
            if (!existingTask.Equals(default(KeyValuePair <ICompileable, CohortIdentificationTaskExecution>)))
            {
                if (existingTask.Value.CountSQL.Equals(newsql))
                {
                    //The SQl is the same but the order or cached
                    if (existingTask.Key.Order != task.Order)//do not delete this if statement, it prevents rewrites to the database where Order asignment has side affects
                    {
                        existingTask.Key.Order = task.Order;
                    }

                    return(existingTask.Key); //existing task has the same SQL
                }
                else
                {
                    //it is different so cancel the old one
                    existingTask.Value.Cancel();

                    //throw away the old task
                    Tasks.Remove(existingTask.Key);

                    //dispose of any resources it's holding onto
                    existingTask.Value.Dispose();
                }
            }


            var isResultsForRootContainer = container != null && container.ID == CohortIdentificationConfiguration.RootCohortAggregateContainer_ID;


            var taskExecution = new CohortIdentificationTaskExecution(cacheServer, newsql, cumulativeSql, source,
                                                                      queryBuilder.CountOfSubQueries,
                                                                      queryBuilder.CountOfCachedSubQueries,
                                                                      isResultsForRootContainer);

            //create a new task
            Tasks.Add(task, taskExecution);

            return(task);
        }
Exemple #6
0
 protected override void OnTransitionedToMainThread(JoinableTask joinableTask, bool canceled)
 {
     this.addToLog(FactoryLogEntry.OuterOnTransitionedToMainThread);
     base.OnTransitionedToMainThread(joinableTask, canceled);
 }
Exemple #7
0
 protected override void OnTransitioningToMainThread(JoinableTask joinableTask)
 {
     this.addToLog(FactoryLogEntry.OuterOnTransitioningToMainThread);
     base.OnTransitioningToMainThread(joinableTask);
 }
 internal void SetSubmoduleStatus(JoinableTask <GitSubmoduleStatus> status)
 {
     _submoduleStatus = status;
 }
Exemple #9
0
 public TaskAwaiter(JoinableTask task)
 {
     awaiter = task.GetAwaiter();
 }
Exemple #10
0
 public JoinableTaskAwaitable(JoinableTask task)
 {
     this.task = task;
 }
 public void RegisterCriticalAsyncTask(JoinableTask joinableTask, bool registerFaultHandler = false)
 {
 }
 public void RegisterAsyncTask(JoinableTask joinableTask, ProjectCriticalOperation operationFlags, bool registerFaultHandler = false)
 {
 }
        /// <summary>
        /// Schedules work to be done on the background,
        /// potentially preempted by another piece of work scheduled in the future,
        /// <paramref name="updateUi" /> indicates whether a single piece of work should occue once all background work is completed.
        /// </summary>
        public void Enqueue(Func <TModel, CancellationToken, Task <TModel> > transformation, bool updateUi)
        {
            // The integrity of our sequential chain depends on this method not being called concurrently.
            // So we require the UI thread.
            if (!_joinableTaskFactory.Context.IsOnMainThread)
            {
                throw new InvalidOperationException($"This method must be callled on the UI thread.");
            }

            if (_token.IsCancellationRequested || _terminated)
            {
                return; // Don't enqueue after computation has stopped.
            }
            // Attempt to commit (CommitIfUnique) will cancel the UI updates. If the commit failed, we still want to update the UI.
            if (_uiCancellation.IsCancellationRequested)
            {
                _uiCancellation = new CancellationTokenSource();
            }

            var previousTask = _lastJoinableTask;
            JoinableTask <TModel> currentTask = null;

            currentTask = _joinableTaskFactory.RunAsync(async() =>
            {
                await Task.Yield();              // Yield to guarantee that currentTask is assigned.
                await _computationTaskScheduler; // Go to the above priority thread. Main thread will return as soon as possible.
                try
                {
                    var previousModel = await previousTask;

                    if (_token.IsCancellationRequested || _terminated)
                    {
                        return(previousModel);
                    }

                    // Previous task finished processing. We are ready to execute next piece of work.
                    var transformedModel = await transformation(previousModel, _token).ConfigureAwait(true);
                    RecentModel          = transformedModel;

                    // TODO: Consider updating UI even if updateUi is false but it wasn't updated yet.
                    if (_lastJoinableTask == currentTask && !_token.IsCancellationRequested && !_terminated)
                    {
                        _callbacks.ComputationFinished(transformedModel);

                        if (updateUi && !_uiCancellation.IsCancellationRequested)
                        {
                            _callbacks.UpdateUI(transformedModel, _uiCancellation.Token).Forget();
                        }
                    }
                    return(transformedModel);
                }
                catch (Exception ex) when(ex is OperationCanceledException || ex is ThreadAbortException)
                {
                    // Disallow enqueuing more tasks
                    _terminated = true;
                    // Close completion
                    _callbacks.DismissDueToCancellation();
                    // Return a task that has not faulted
                    return(default(TModel));
                }
                catch (Exception ex)
                {
                    // Disallow enqueuing more tasks
                    _terminated = true;
                    // Log the issue
                    _guardedOperations.HandleException(this, ex);
                    // Close completion
                    _callbacks.DismissDueToError();
                    // Return a task that has not faulted
                    return(default(TModel));
                }
            });

            _lastJoinableTask = currentTask;
        }
Exemple #14
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);
            }
        }
Exemple #15
0
        public Task <T> LoadedProjectAsync <T>(Func <Task <T> > action)
        {
            JoinableTask <T> joinable = _tasksService.LoadedProjectAsync(action);

            return(joinable.Task);
        }
 public static void FileAndForget(this JoinableTask joinableTask, Func <Exception, bool> fileOnlyIf = null)
 {
     joinableTask.Task.FileAndForget(fileOnlyIf);
 }
 /// <summary>
 /// Logs error information to the Output Window if the given <see cref="JoinableTask" /> faults.
 /// </summary>
 /// <remarks>
 /// This is the JoinableTask equivalent of <see cref="FireAndForget(System.Threading.Tasks.Task, bool)"/>
 /// </remarks>
 public static void FireAndForget(this JoinableTask joinableTask, bool logOnFailure = true)
 {
     FireAndForget(joinableTask.Task, logOnFailure);
 }
Exemple #18
0
 /// <summary>
 /// A helper method that just blocks on the completion of a JoinableTask.
 /// </summary>
 /// <remarks>
 /// This method is explicitly defined rather than using an anonymous method because
 /// we do NOT want the calling method's name embedded into this method's name by the compiler
 /// so that we can verify based on method name.
 /// </remarks>
 private static void OnHangDetected_BlockingMethodHelper(JoinableTask jt)
 {
     jt.Join();
 }
Exemple #19
0
            public Service(
                IAsyncServiceProvider2 serviceProvider,
                IThreadingContext threadingContext,
                IAsynchronousOperationListener listener
                )
            {
                _serviceProvider  = serviceProvider;
                _threadingContext = threadingContext;

                _loadHubClientPackage = _threadingContext.JoinableTaskFactory.RunAsync(
                    async() =>
                {
                    // Use the disposal token, since the caller's cancellation token will apply instead to the
                    // JoinAsync operation in GetProgressStageStatusAsync.
                    await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(
                        alwaysYield: true,
                        _threadingContext.DisposalToken
                        );

                    // Make sure the HubClient package is loaded, since we rely on it for proffered OOP services
                    var shell = await _serviceProvider
                                .GetServiceAsync <SVsShell, IVsShell7>()
                                .ConfigureAwait(true);
                    Assumes.Present(shell);

                    await shell.LoadPackageAsync(Guids.GlobalHubClientPackageGuid);
                }
                    );

                _progressStageStatus = _threadingContext.JoinableTaskFactory.RunAsync(
                    async() =>
                {
                    // pre-emptively make sure event is subscribed. if APIs are called before it is done, calls will be blocked
                    // until event subscription is done
                    using var asyncToken = listener.BeginAsyncOperation(
                              "StatusChanged_EventSubscription"
                              );

                    await threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(
                        alwaysYield: true,
                        _threadingContext.DisposalToken
                        );
                    var service = await serviceProvider
                                  .GetServiceAsync <
                        SVsOperationProgress,
                        IVsOperationProgressStatusService
                        >(throwOnFailure: false)
                                  .ConfigureAwait(true);
                    if (service is null)
                    {
                        return(null);
                    }

                    var status = service.GetStageStatusForSolutionLoad(
                        CommonOperationProgressStageIds.Intellisense
                        );
                    status.PropertyChanged += (_, _) =>
                                              StatusChanged?.Invoke(this, EventArgs.Empty);

                    return(status);
                }
                    );
            }