예제 #1
0
        public Task WaitForCompleteAsync(AnalysisPriority priority = AnalysisPriority.None)
        {
            var task = new WaitAnalyzableTask();

            Enqueue(task, priority);
            return(task.Task);
        }
예제 #2
0
        /// <summary>
        /// Queues the specified work to run in analysis queue.
        /// Exceptions are rethrown to the caller and don't affect queue processing loop.
        /// </summary>
        /// <param name="function">The work to execute</param>
        /// <param name="priority"></param>
        /// <returns></returns>
        public Task ExecuteInQueueAsync(Func <CancellationToken, Task> function, AnalysisPriority priority)
        {
            // If we are inside the queue already, simply call the function
            if (Current == this)
            {
                return(function(_ppc.CancellationToken));
            }

            var item = new ExecuteInQueueAsyncItem <bool>(function);

            Enqueue(item, item.Handler, priority);
            return(item.Task);
        }
예제 #3
0
        public void Enqueue(IAnalyzable item, AnalysisPriority priority)
        {
            ThrowIfDisposed();
            var iPri = (int)priority;

            if (iPri < 0 || iPri > _queue.Length)
            {
                throw new ArgumentException("priority");
            }

            lock (_queueLock) {
                // see if we have the item in the queue anywhere...
                for (var i = 0; i < _queue.Length; i++)
                {
                    if (_queue[i].Remove(item))
                    {
                        Interlocked.Decrement(ref _analysisPending);

                        var oldPri = (AnalysisPriority)i;

                        if (oldPri > priority)
                        {
                            // if it was at a higher priority then our current
                            // priority go ahead and raise the new entry to our
                            // old priority
                            priority = oldPri;
                        }

                        break;
                    }
                }

                // enqueue the work item
                Interlocked.Increment(ref _analysisPending);
                if (priority == AnalysisPriority.High)
                {
                    // always try and process high pri items immediately
                    _queue[iPri].Insert(0, item);
                }
                else
                {
                    _queue[iPri].Add(item);
                }
                try {
                    _workEvent.Set();
                } catch (IOException) {
                } catch (ObjectDisposedException) {
                    // Queue was closed while we were running
                }
            }
        }
예제 #4
0
 private IAnalyzable GetNextItem(out AnalysisPriority priority)
 {
     for (int i = PriorityCount - 1; i >= 0; i--)
     {
         if (_queue[i].Count > 0)
         {
             var res = _queue[i][0];
             _queue[i].RemoveAt(0);
             priority = (AnalysisPriority)i;
             return(res);
         }
     }
     priority = AnalysisPriority.None;
     return(null);
 }
예제 #5
0
 private IAnalyzable GetNextItem(out AnalysisPriority priority)
 {
     for (var i = PriorityCount - 1; i >= 0; i--)
     {
         if (_queue[i].Count > 0)
         {
             var res = _queue[i][0];
             _queue[i].RemoveAt(0);
             Interlocked.Decrement(ref _analysisPending);
             priority = (AnalysisPriority)i;
             return(res);
         }
     }
     priority = AnalysisPriority.None;
     return(null);
 }
예제 #6
0
        private async Task HandleAnalyzable(IAnalyzable item, AnalysisPriority priority, CancellationToken cancellationToken)
        {
            if (item is IGroupableAnalysisProjectEntry groupable)
            {
                var added = _enqueuedGroups.Add(groupable.AnalysisGroup);
                if (added)
                {
                    Enqueue(new GroupAnalysis(groupable.AnalysisGroup, this), priority);
                }

                groupable.Analyze(cancellationToken, true);
            }
            else
            {
                item.Analyze(cancellationToken);
            }
        }
예제 #7
0
        internal void EnqueueItem(IDocument doc, AnalysisPriority priority = AnalysisPriority.Normal, bool enqueueForAnalysis = true)
        {
            ThrowIfDisposed();
            var pending = _pendingAnalysisEnqueue.Incremented();

            try {
                Task <IAnalysisCookie> cookieTask;
                using (GetDocumentParseCounter(doc, out var count)) {
                    if (count > 3)
                    {
                        // Rough check to prevent unbounded queueing. If we have
                        // multiple parses in queue, we will get the latest doc
                        // version in one of the ones to come.
                        return;
                    }
                    TraceMessage($"Parsing document {doc.DocumentUri}");
                    cookieTask = _parseQueue.Enqueue(doc, Analyzer.LanguageVersion);
                }

                if (doc is ProjectEntry entry)
                {
                    entry.ResetCompleteAnalysis();
                }

                AnalysisQueued(doc.DocumentUri);
                // The call must be fire and forget, but should not be yielding.
                // It is called from DidChangeTextDocument which must fully finish
                // since otherwise Complete() may come before the change is enqueued
                // for processing and the completion list will be driven off the stale data.
                var p = pending;
                cookieTask.ContinueWith(t => {
                    if (t.IsFaulted)
                    {
                        // Happens when file got deleted before processing
                        p.Dispose();
                        LogMessage(MessageType.Error, t.Exception.Message);
                        return;
                    }
                    OnDocumentChangeProcessingComplete(doc, t.Result as VersionCookie, enqueueForAnalysis, priority, p);
                }).DoNotWait();
                pending = null;
            } finally {
                pending?.Dispose();
            }
        }
예제 #8
0
        public void Enqueue(TAnalyzedType item, AnalysisPriority priority)
        {
            int iPri = (int)priority;

            if (iPri < 0 || iPri > _queue.Length)
            {
                throw new ArgumentException("priority");
            }

            lock (_queueLock) {
                // see if we have the item in the queue anywhere...
                for (int i = 0; i < _queue.Length; i++)
                {
                    if (_queue[i].Remove(item))
                    {
                        AnalysisPriority oldPri = (AnalysisPriority)i;

                        if (oldPri > priority)
                        {
                            // if it was at a higher priority then our current
                            // priority go ahead and raise the new entry to our
                            // old priority
                            priority = oldPri;
                        }

                        break;
                    }
                }

                // enqueue the work item
                if (priority == AnalysisPriority.High)
                {
                    // always try and process high pri items immediately
                    _queue[iPri].Insert(0, item);
                }
                else
                {
                    _queue[iPri].Add(item);
                }
                _event.Set();
            }
        }
예제 #9
0
        public void Enqueue(IAnalyzable item, AnalysisPriority priority) {
            int iPri = (int)priority;

            if (iPri < 0 || iPri > _queue.Length) {
                throw new ArgumentException("priority");
            }

            lock (_queueLock) {
                // see if we have the item in the queue anywhere...
                for (int i = 0; i < _queue.Length; i++) {
                    if (_queue[i].Remove(item)) {
                        Interlocked.Decrement(ref _analysisPending);

                        AnalysisPriority oldPri = (AnalysisPriority)i;

                        if (oldPri > priority) {
                            // if it was at a higher priority then our current
                            // priority go ahead and raise the new entry to our
                            // old priority
                            priority = oldPri;
                        }

                        break;
                    }
                }

                // enqueue the work item
                Interlocked.Increment(ref _analysisPending);
                if (priority == AnalysisPriority.High) {
                    // always try and process high pri items immediately
                    _queue[iPri].Insert(0, item);
                } else {
                    _queue[iPri].Add(item);
                }
                try {
                    _workEvent.Set();
                } catch (ObjectDisposedException) {
                    // Queue was closed while we were running
                }
            }
        }
예제 #10
0
        private async Task HandleAnalyzable(IAnalyzable item, AnalysisPriority priority, CancellationToken cancellationToken)
        {
            if (item is IGroupableAnalysisProjectEntry groupable)
            {
                var added = _enqueuedGroups.Add(groupable.AnalysisGroup);
                if (added)
                {
                    try {
                        Enqueue(new GroupAnalysis(groupable.AnalysisGroup, this), priority);
                    } catch (ObjectDisposedException) when(_ppc.IsDisposed)
                    {
                        return;
                    }
                }

                groupable.Analyze(cancellationToken, true);
            }
            else
            {
                item.Analyze(cancellationToken);
            }
        }
 private IAnalyzable GetNextItem(out AnalysisPriority priority) {
     for (int i = PriorityCount - 1; i >= 0; i--) {
         if (_queue[i].Count > 0) {
             var res = _queue[i][0];
             _queue[i].RemoveAt(0);
             Interlocked.Decrement(ref _analysisPending);
             priority = (AnalysisPriority)i;
             return res;
         }
     }
     priority = AnalysisPriority.None;
     return null;
 }
예제 #12
0
 private void Enqueue(object key, Func <CancellationToken, Task> handler, AnalysisPriority priority)
 => _ppc.Produce(new QueueItem(key, handler), (int)priority);
예제 #13
0
 public void Enqueue(IAnalyzable item, AnalysisPriority priority)
 {
     Enqueue(item, ct => HandleAnalyzable(item, priority, ct), priority);
 }
예제 #14
0
파일: Server.cs 프로젝트: mstahl00/PTVS
        private void OnDocumentChangeProcessingComplete(IDocument doc, VersionCookie vc, bool enqueueForAnalysis, AnalysisPriority priority, IDisposable disposeWhenEnqueued)
        {
            try {
                if (vc != null)
                {
                    foreach (var kv in vc.GetAllParts(doc.DocumentUri))
                    {
                        ParseComplete(kv.Key, kv.Value.Version);
                    }
                }
                else
                {
                    ParseComplete(doc.DocumentUri, 0);
                }

                if (doc is IAnalyzable analyzable && enqueueForAnalysis)
                {
                    TraceMessage($"Enqueing document {doc.DocumentUri} for analysis");
                    _queue.Enqueue(analyzable, priority);
                }

                disposeWhenEnqueued?.Dispose();
                disposeWhenEnqueued = null;
                var openedFile = _openFiles.GetDocument(doc.DocumentUri);
                if (vc != null)
                {
                    var reported = openedFile.LastReportedDiagnostics;
                    lock (reported) {
                        foreach (var kv in vc.GetAllParts(doc.DocumentUri))
                        {
                            var part = _projectFiles.GetPart(kv.Key);
                            if (!reported.TryGetValue(part, out var lastVersion) || lastVersion.Version < kv.Value.Version)
                            {
                                reported[part] = kv.Value;
                                PublishDiagnostics(new PublishDiagnosticsEventArgs {
                                    uri         = kv.Key,
                                    diagnostics = kv.Value.Diagnostics,
                                    _version    = kv.Value.Version
                                });
                            }
                        }
                    }
                }
            } catch (BadSourceException) {
            } catch (OperationCanceledException ex) {
                LogMessage(MessageType.Warning, $"Parsing {doc.DocumentUri} cancelled");
                TraceMessage($"{ex}");
            } catch (Exception ex) {
                LogMessage(MessageType.Error, ex.ToString());
            } finally {
                disposeWhenEnqueued?.Dispose();
            }
        }
예제 #15
0
파일: Server.cs 프로젝트: Jiaoma/PTVS
        private void OnDocumentChangeProcessingComplete(IDocument doc, VersionCookie vc, bool enqueueForAnalysis, AnalysisPriority priority, IDisposable disposeWhenEnqueued)
        {
            ThrowIfDisposed();
            try {
                if (vc != null)
                {
                    foreach (var kv in vc.GetAllParts(doc.DocumentUri))
                    {
                        ParseComplete(kv.Key, kv.Value.Version);
                    }
                }
                else
                {
                    ParseComplete(doc.DocumentUri, 0);
                }

                if (doc is IAnalyzable analyzable && enqueueForAnalysis)
                {
                    TraceMessage($"Enqueing document {doc.DocumentUri} for analysis");
                    _queue.Enqueue(analyzable, priority);
                }

                disposeWhenEnqueued?.Dispose();
                disposeWhenEnqueued = null;
                if (vc != null)
                {
                    _editorFiles.GetDocument(doc.DocumentUri).UpdateParseDiagnostics(vc, doc.DocumentUri);
                }
            } catch (BadSourceException) {
            } catch (OperationCanceledException ex) {
                LogMessage(MessageType.Warning, $"Parsing {doc.DocumentUri} cancelled");
                TraceMessage($"{ex}");
            } catch (Exception ex) {
                LogMessage(MessageType.Error, ex.ToString());
            } finally {
                disposeWhenEnqueued?.Dispose();
            }
        }