private async Task OnDependenciesSnapshotChangedAsync(SnapshotChangedEventArgs e)
        {
            DependenciesSnapshot snapshot = e.Snapshot;

            if (_tasksService.UnloadCancellationToken.IsCancellationRequested || e.Token.IsCancellationRequested)
            {
                return;
            }

            // Take the highest priority view provider
            IDependenciesTreeViewProvider?viewProvider = _viewProviders.FirstOrDefault()?.Value;

            if (viewProvider == null)
            {
                return;
            }

            try
            {
                await SubmitTreeUpdateAsync(UpdateTreeAsync, _treeUpdateCancellationSeries.CreateNext(e.Token));
            }
            catch (OperationCanceledException)
            {
            }
            catch (Exception ex)
            {
                // We do not expect any exception when we call SubmitTreeUpdateAsync, but we don't want to leak an exception here.
                // Because it will fault the dataflow block which stops further tree updates.
                _ = ProjectFaultHandlerService.ReportFaultAsync(ex, UnconfiguredProject);
            }

            return;

            async Task <TreeUpdateResult> UpdateTreeAsync(
                IProjectVersionedValue <IProjectTreeSnapshot>?treeSnapshot,
                ConfiguredProjectExports?configuredProjectExports,
                CancellationToken cancellationToken)
            {
                Assumes.NotNull(treeSnapshot); // we specify the initial tree so it will not be null here

                IProjectTree dependenciesNode = treeSnapshot.Value.Tree;

                if (!cancellationToken.IsCancellationRequested)
                {
                    dependenciesNode = await viewProvider.BuildTreeAsync(dependenciesNode, snapshot, cancellationToken);

                    if (_treeTelemetryService.IsActive)
                    {
                        await _treeTelemetryService.ObserveTreeUpdateCompletedAsync(snapshot.MaximumVisibleDiagnosticLevel != DiagnosticLevel.None);
                    }
                }

                return(new TreeUpdateResult(dependenciesNode));
            }
        }
        private async Task OnDependenciesSnapshotChangedAsync(SnapshotChangedEventArgs e)
        {
            DependenciesSnapshot snapshot = e.Snapshot;

            if (_tasksService.UnloadCancellationToken.IsCancellationRequested || e.Token.IsCancellationRequested)
            {
                return;
            }

            // Take the highest priority view provider
            IDependenciesTreeViewProvider?viewProvider = _viewProviders.FirstOrDefault()?.Value;

            if (viewProvider == null)
            {
                return;
            }

            try
            {
                await SubmitTreeUpdateAsync(UpdateTreeAsync, _treeUpdateCancellationSeries.CreateNext(e.Token));
            }
            catch (OperationCanceledException)
            {
            }
            catch (Exception ex)
            {
                // We do not expect any exception when we call SubmitTreeUpdateAsync, but we don't want to leak an exception here.
                // Because it will fail the dataflow block and stops updating the project tree silently.
                _ = ProjectFaultHandlerService.ReportFaultAsync(ex, UnconfiguredProject);
            }

            return;

            async Task <TreeUpdateResult> UpdateTreeAsync(
                IProjectVersionedValue <IProjectTreeSnapshot> treeSnapshot,
                ConfiguredProjectExports configuredProjectExports,
                CancellationToken cancellationToken)
            {
                IProjectTree dependenciesNode = treeSnapshot.Value.Tree;

                if (!cancellationToken.IsCancellationRequested)
                {
                    dependenciesNode = await viewProvider !.BuildTreeAsync(dependenciesNode, snapshot, cancellationToken);

                    if (_treeTelemetryService.IsActive)
                    {
                        await _treeTelemetryService.ObserveTreeUpdateCompletedAsync(snapshot.HasReachableVisibleUnresolvedDependency);
                    }
                }

                return(new TreeUpdateResult(dependenciesNode));
            }
        }
        private void OnDependenciesSnapshotChanged(object sender, SnapshotChangedEventArgs e)
        {
            IDependenciesSnapshot snapshot = e.Snapshot;

            if (snapshot == null)
            {
                return;
            }

            if (_tasksService.UnloadCancellationToken.IsCancellationRequested || e.Token.IsCancellationRequested)
            {
                return;
            }

            // Take the highest priority view provider
            IDependenciesTreeViewProvider viewProvider = _viewProviders.FirstOrDefault()?.Value;

            if (viewProvider == null)
            {
                return;
            }

            try
            {
                _ = SubmitTreeUpdateAsync(
                    async(treeSnapshot, configuredProjectExports, cancellationToken) =>
                {
                    IProjectTree dependenciesNode = treeSnapshot.Value.Tree;

                    if (!cancellationToken.IsCancellationRequested)
                    {
                        dependenciesNode = await viewProvider.BuildTreeAsync(dependenciesNode, snapshot, cancellationToken);

                        await _treeTelemetryService.ObserveTreeUpdateCompletedAsync(snapshot.HasUnresolvedDependency);
                    }

                    // TODO We still are getting mismatched data sources and need to figure out better
                    // way of merging, mute them for now and get to it in U1
                    return(new TreeUpdateResult(dependenciesNode));
                },
                    _treeUpdateCancellationSeries.CreateNext(e.Token));
            }
            catch (OperationCanceledException)
            {
            }
            catch (Exception ex)
            {
                // We do not expect any exception when we call SubmitTreeUpdateAsync, but we don't want to leak an exception here.
                // Because it will fail the dataflow block and stops updating the project tree silently.
                _ = ProjectFaultHandlerService.ReportFaultAsync(ex, UnconfiguredProject);
            }
        }