示例#1
0
        private void ParseDocumentAsync(Document document)
        {
            var cancellationTokenSource = new CancellationTokenSource();

            using (_stateLock.DisposableWrite())
            {
                _workMap = _workMap.Add(document.Id, cancellationTokenSource);
            }

            var cancellationToken = cancellationTokenSource.Token;

            var task = _taskScheduler.ScheduleTask(
                () => document.GetSyntaxTreeAsync(cancellationToken),
                "BackgroundParser.ParseDocumentAsync",
                cancellationToken);

            // Always ensure that we mark this work as done from the workmap.
            task.SafeContinueWith(
                _ =>
            {
                using (_stateLock.DisposableWrite())
                {
                    // Check that we are still the active parse in the workmap before we remove it.
                    // Concievably if this continuation got delayed and another parse was put in, we might
                    // end up removing the tracking for another in-flight task.
                    if (_workMap.TryGetValue(document.Id, out var sourceInMap) && sourceInMap == cancellationTokenSource)
                    {
                        _workMap = _workMap.Remove(document.Id);
                    }
                }
            }, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Default);
        }
示例#2
0
        private void ParseDocumentAsync(Document document)
        {
            var cancellationTokenSource = new CancellationTokenSource();

            using (_stateLock.DisposableWrite())
            {
                _workMap = _workMap.Add(document.Id, cancellationTokenSource);
            }

            var cancellationToken = cancellationTokenSource.Token;

            var task = _taskScheduler.ScheduleTask(
                () => document.GetSyntaxTreeAsync(cancellationToken),
                "BackgroundParser.ParseDocumentAsync",
                cancellationToken);

            // Always ensure that we mark this work as done from the workmap.
            task.SafeContinueWith(
                _ =>
            {
                using (_stateLock.DisposableWrite())
                {
                    _workMap = _workMap.Remove(document.Id);
                }
            }, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Default);
        }
示例#3
0
        private void BuildCompilationsAsync(
            Solution solution,
            ProjectId initialProject,
            ISet <ProjectId> allProjects)
        {
            var cancellationToken = _cancellationSource.Token;

            _compilationScheduler.ScheduleTask(
                () => BuildCompilationsAsync(solution, initialProject, allProjects, cancellationToken),
                "BackgroundCompiler.BuildCompilationsAsync",
                cancellationToken);
        }
示例#4
0
 private void OnGlobalOptionServiceOptionChanged(object sender, OptionChangedEventArgs e)
 {
     _taskQueue?.ScheduleTask(() =>
     {
         // Ensure we grab the event handlers inside the scheduled task to prevent a race of people unsubscribing
         // but getting the event later on the UI thread
         var eventHandlers = GetEventHandlers();
         foreach (var handler in eventHandlers)
         {
             handler(this, e);
         }
     }, "OptionsService.SetOptions");
 }
示例#5
0
            private void OnGlobalOptionServiceOptionChanged(object sender, OptionChangedEventArgs e)
            {
                var eventHandlers = GetEventHandlers();

                if (eventHandlers.Length > 0)
                {
                    _taskQueue?.ScheduleTask(() =>
                    {
                        foreach (var handler in eventHandlers)
                        {
                            handler(this, e);
                        }
                    }, "OptionsService.SetOptions");
                }
            }
示例#6
0
        private void ParseDocumentAsync(Document document)
        {
            var cancellationTokenSource = new CancellationTokenSource();

            using (_stateLock.DisposableWrite())
            {
                _workMap = _workMap.Add(document.Id, cancellationTokenSource);
            }

            var cancellationToken = cancellationTokenSource.Token;

            // We end up creating a chain of parsing tasks that each attempt to produce
            // the appropriate syntax tree for any given document. Once we start work to create
            // the syntax tree for a given document, we don't want to stop.
            // Otherwise we can end up in the unfortunate scenario where we keep cancelling work,
            // and then having the next task re-do the work we were just in the middle of.
            // By not cancelling, we can reuse the useful results of previous tasks when performing later steps in the chain.
            //
            // we still cancel whole task if the task didn't start yet. we just don't cancel if task is started but not finished yet.
            var task = _taskScheduler.ScheduleTask(
                () => document.GetSyntaxTreeAsync(CancellationToken.None),
                "BackgroundParser.ParseDocumentAsync",
                cancellationToken);

            // Always ensure that we mark this work as done from the workmap.
            task.SafeContinueWith(
                _ =>
            {
                using (_stateLock.DisposableWrite())
                {
                    // Check that we are still the active parse in the workmap before we remove it.
                    // Concievably if this continuation got delayed and another parse was put in, we might
                    // end up removing the tracking for another in-flight task.
                    if (_workMap.TryGetValue(document.Id, out var sourceInMap) && sourceInMap == cancellationTokenSource)
                    {
                        _workMap = _workMap.Remove(document.Id);
                    }
                }
            }, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Default);
        }
示例#7
0
 /// <summary>
 /// Executes an action as a background task, as part of a sequential queue of tasks.
 /// </summary>
 protected internal Task ScheduleTask(Action action, string taskName = "Workspace.Task")
 {
     return(_taskQueue.ScheduleTask(action, taskName));
 }