public TagSource( ITextView textViewOpt, ITextBuffer subjectBuffer, AbstractAsynchronousTaggerProvider <TTag> dataSource, IAsynchronousOperationListener asyncListener, IForegroundNotificationService notificationService) { if (dataSource.SpanTrackingMode == SpanTrackingMode.Custom) { throw new ArgumentException("SpanTrackingMode.Custom not allowed.", "spanTrackingMode"); } _subjectBuffer = subjectBuffer; _textViewOpt = textViewOpt; _dataSource = dataSource; _asyncListener = asyncListener; _notificationService = notificationService; _tagSpanComparer = new TagSpanComparer(_dataSource.TagComparer); DebugRecordInitialStackTrace(); _workQueue = new AsynchronousSerialWorkQueue(asyncListener); this.CachedTagTrees = ImmutableDictionary.Create <ITextBuffer, TagSpanIntervalTree <TTag> >(); _eventSource = CreateEventSource(); Connect(); // Kick off a task to compute the initial set of tags. RecalculateTagsOnChanged(new TaggerEventArgs(TaggerDelay.Short)); }
public void TestMultipleBackgroundAction() { var exportProvider = EditorTestCompositions.EditorFeatures.ExportProviderFactory.CreateExportProvider(); var threadingContext = exportProvider.GetExportedValue <IThreadingContext>(); var listenerProvider = exportProvider.GetExportedValue <IAsynchronousOperationListenerProvider>(); // Test that background actions don't run at the same time. var worker = new AsynchronousSerialWorkQueue(threadingContext, listenerProvider.GetListener("Test")); var doneEvent = new AutoResetEvent(false); var action1Ran = false; var action2Ran = false; worker.EnqueueBackgroundWork(() => { Assert.NotSame(_foregroundSyncContext, SynchronizationContext.Current); action1Ran = true; // Simulate work to ensure that if tasks overlap that we will // see it. Thread.Sleep(1000); Assert.False(action2Ran); }, "Test", CancellationToken.None); worker.EnqueueBackgroundWork(() => { Assert.NotSame(_foregroundSyncContext, SynchronizationContext.Current); action2Ran = true; doneEvent.Set(); }, "Test", CancellationToken.None); doneEvent.WaitOne(); Assert.True(action1Ran); Assert.True(action2Ran); }
public TagSource( ITextView textViewOpt, ITextBuffer subjectBuffer, AbstractAsynchronousTaggerProvider <TTag> dataSource, IAsynchronousOperationListener asyncListener, IForegroundNotificationService notificationService) : base(dataSource.ThreadingContext) { if (dataSource.SpanTrackingMode == SpanTrackingMode.Custom) { throw new ArgumentException("SpanTrackingMode.Custom not allowed.", "spanTrackingMode"); } _subjectBuffer = subjectBuffer; _textViewOpt = textViewOpt; _dataSource = dataSource; _asyncListener = asyncListener; _notificationService = notificationService; _tagSpanComparer = new TagSpanComparer(_dataSource.TagComparer); DebugRecordInitialStackTrace(); _workQueue = new AsynchronousSerialWorkQueue(ThreadingContext, asyncListener); this.CachedTagTrees = ImmutableDictionary.Create <ITextBuffer, TagSpanIntervalTree <TTag> >(); _eventSource = CreateEventSource(); Connect(); // Start computing the initial set of tags immediately. We want to get the UI // to a complete state as soon as possible. ComputeInitialTags(); }
public TagComputer( ITextBuffer subjectBuffer, IForegroundNotificationService notificationService, IAsynchronousOperationListener asyncListener, ClassificationTypeMap typeMap, SyntacticClassificationTaggerProvider taggerProvider) { _subjectBuffer = subjectBuffer; _notificationService = notificationService; _listener = asyncListener; _typeMap = typeMap; _taggerProvider = taggerProvider; _workQueue = new AsynchronousSerialWorkQueue(asyncListener); _reportChangeCancellationSource = new CancellationTokenSource(); _lastLineCache = new LastLineCache(); _workspaceRegistration = Workspace.GetWorkspaceRegistration(subjectBuffer.AsTextContainer()); _workspaceRegistration.WorkspaceChanged += OnWorkspaceRegistrationChanged; if (_workspaceRegistration.Workspace != null) { ConnectToWorkspace(_workspaceRegistration.Workspace); } }
public void TestBackgroundAction() { var exportProvider = EditorTestCompositions.EditorFeatures.ExportProviderFactory.CreateExportProvider(); var threadingContext = exportProvider.GetExportedValue <IThreadingContext>(); var listenerProvider = exportProvider.GetExportedValue <IAsynchronousOperationListenerProvider>(); var worker = new AsynchronousSerialWorkQueue( threadingContext, listenerProvider.GetListener("Test") ); var doneEvent = new AutoResetEvent(initialState: false); var actionRan = false; worker.EnqueueBackgroundWork( () => { // Assert.NotNull(SynchronizationContext.Current); Assert.NotSame(_foregroundSyncContext, SynchronizationContext.Current); actionRan = true; doneEvent.Set(); }, GetType().Name + ".TestBackgroundAction", CancellationToken.None ); doneEvent.WaitOne(); Assert.True(actionRan); }
public void TestMultipleBackgroundAction() { // Test that background actions don't run at the same time. var worker = new AsynchronousSerialWorkQueue(AsynchronousOperationListenerProvider.NullListener); var doneEvent = new AutoResetEvent(false); var action1Ran = false; var action2Ran = false; worker.EnqueueBackgroundWork(() => { Assert.NotSame(_foregroundSyncContext, SynchronizationContext.Current); action1Ran = true; // Simulate work to ensure that if tasks overlap that we will // see it. Thread.Sleep(1000); Assert.False(action2Ran); }, "Test", CancellationToken.None); worker.EnqueueBackgroundWork(() => { Assert.NotSame(_foregroundSyncContext, SynchronizationContext.Current); action2Ran = true; doneEvent.Set(); }, "Test", CancellationToken.None); doneEvent.WaitOne(); Assert.True(action1Ran); Assert.True(action2Ran); }
public TagComputer( ITextBuffer subjectBuffer, IForegroundNotificationService notificationService, IAsynchronousOperationListener asyncListener, ClassificationTypeMap typeMap, SyntacticClassificationTaggerProvider taggerProvider, IViewSupportsClassificationService viewSupportsClassificationServiceOpt, ITextBufferAssociatedViewService associatedViewService, IEditorClassificationService editorClassificationService, string languageName) { _subjectBuffer = subjectBuffer; _notificationService = notificationService; _listener = asyncListener; _typeMap = typeMap; _taggerProvider = taggerProvider; _viewSupportsClassificationServiceOpt = viewSupportsClassificationServiceOpt; _associatedViewService = associatedViewService; _editorClassificationService = editorClassificationService; _languageName = languageName; _workQueue = new AsynchronousSerialWorkQueue(asyncListener); _reportChangeCancellationSource = new CancellationTokenSource(); _lastLineCache = new LastLineCache(); _workspaceRegistration = Workspace.GetWorkspaceRegistration(subjectBuffer.AsTextContainer()); _workspaceRegistration.WorkspaceChanged += OnWorkspaceRegistrationChanged; ConnectToWorkspace(_workspaceRegistration.Workspace); }
public DiagnosticsTagSource(AbstractAggregatedDiagnosticsTagSource <TTag> owner) { _owner = owner; _workQueue = new AsynchronousSerialWorkQueue(_owner.Listener); _lastDiagnostics = IntervalTree <Data> .Empty; }
public void TestBackgroundCancelMultipleActions() { var exportProvider = EditorTestCompositions.EditorFeatures.ExportProviderFactory.CreateExportProvider(); var threadingContext = exportProvider.GetExportedValue <IThreadingContext>(); var listenerProvider = exportProvider.GetExportedValue <IAsynchronousOperationListenerProvider>(); // Ensure that multiple background actions are cancelled if they // use the same cancellation token. var worker = new AsynchronousSerialWorkQueue(threadingContext, listenerProvider.GetListener("Test")); var taskRunningEvent = new AutoResetEvent(false); var cancelEvent = new AutoResetEvent(false); var doneEvent = new AutoResetEvent(false); var source = new CancellationTokenSource(); var cancellationToken = source.Token; var action1Ran = false; var action2Ran = false; worker.EnqueueBackgroundWork(() => { action1Ran = true; Assert.NotSame(_foregroundSyncContext, SynchronizationContext.Current); Assert.False(cancellationToken.IsCancellationRequested); taskRunningEvent.Set(); cancelEvent.WaitOne(); cancellationToken.ThrowIfCancellationRequested(); Assert.True(false); }, "Test", source.Token); // We should not run this action. worker.EnqueueBackgroundWork(() => { action2Ran = true; Assert.False(true); }, "Test", source.Token); taskRunningEvent.WaitOne(); source.Cancel(); cancelEvent.Set(); try { worker.GetTestAccessor().WaitUntilCompletion(); Assert.True(false); } catch (AggregateException ae) { Assert.IsAssignableFrom <OperationCanceledException>(ae.InnerException); } Assert.True(action1Ran); Assert.False(action2Ran); }
public ErrorsSnapshotFactory(IDiagnosticService diagnosticService, DocumentId documentId) { _diagnosticService = diagnosticService; _documentId = documentId; _workQueue = new AsynchronousSerialWorkQueue(new AsynchronousOperationListener()); _currentSnapshot = new ErrorsSnapshot(ImmutableArray <MappedDiagnostic> .Empty, 0); }
public void TestBackgroundCancelMultipleActions() { // Ensure that multiple background actions are cancelled if they // use the same cancellation token. var listener = new AggregateAsynchronousOperationListener(Enumerable.Empty <Lazy <IAsynchronousOperationListener, FeatureMetadata> >(), "Test"); var worker = new AsynchronousSerialWorkQueue(listener); var taskRunningEvent = new AutoResetEvent(false); var cancelEvent = new AutoResetEvent(false); var doneEvent = new AutoResetEvent(false); var source = new CancellationTokenSource(); var cancellationToken = source.Token; var action1Ran = false; var action2Ran = false; worker.EnqueueBackgroundWork(() => { action1Ran = true; Assert.NotSame(_foregroundSyncContext, SynchronizationContext.Current); Assert.False(cancellationToken.IsCancellationRequested); taskRunningEvent.Set(); cancelEvent.WaitOne(); cancellationToken.ThrowIfCancellationRequested(); Assert.True(false); }, "Test", source.Token); // We should not run this action. worker.EnqueueBackgroundWork(() => { action2Ran = true; Assert.False(true); }, "Test", source.Token); taskRunningEvent.WaitOne(); source.Cancel(); cancelEvent.Set(); try { worker.WaitUntilCompletion_ForTestingPurposesOnly(); Assert.True(false); } catch (AggregateException ae) { Assert.IsAssignableFrom <OperationCanceledException>(ae.InnerException); } Assert.True(action1Ran); Assert.False(action2Ran); }
public CompilationAvailableTaggerEventSource( ITextBuffer subjectBuffer, IThreadingContext threadingContext, IAsynchronousOperationListener asyncListener, params ITaggerEventSource[] eventSources) { _subjectBuffer = subjectBuffer; _asyncListener = asyncListener; _underlyingSource = TaggerEventSources.Compose(eventSources); _workQueue = new AsynchronousSerialWorkQueue(threadingContext, asyncListener); }
protected TagSource( ITextBuffer subjectBuffer, IForegroundNotificationService notificationService, IAsynchronousOperationListener asyncListener) { this.SubjectBuffer = subjectBuffer; _notificationService = notificationService; this.Listener = asyncListener; this.WorkQueue = new AsynchronousSerialWorkQueue(asyncListener); StartInitialRefresh(); }
public void TestBackgroundCancel1() { var exportProvider = EditorTestCompositions.EditorFeatures.ExportProviderFactory.CreateExportProvider(); var threadingContext = exportProvider.GetExportedValue <IThreadingContext>(); var listenerProvider = exportProvider.GetExportedValue <IAsynchronousOperationListenerProvider>(); // Ensure that we can cancel a background action. var worker = new AsynchronousSerialWorkQueue( threadingContext, listenerProvider.GetListener("Test") ); var taskRunningEvent = new AutoResetEvent(false); var cancelEvent = new AutoResetEvent(false); var doneEvent = new AutoResetEvent(false); var source = new CancellationTokenSource(); var cancellationToken = source.Token; var actionRan = false; worker.EnqueueBackgroundWork( () => { actionRan = true; Assert.NotSame(_foregroundSyncContext, SynchronizationContext.Current); Assert.False(cancellationToken.IsCancellationRequested); taskRunningEvent.Set(); cancelEvent.WaitOne(); Assert.True(cancellationToken.IsCancellationRequested); doneEvent.Set(); }, "Test", source.Token ); taskRunningEvent.WaitOne(); source.Cancel(); cancelEvent.Set(); doneEvent.WaitOne(); Assert.True(actionRan); }
public void TestBackgroundAction() { var worker = new AsynchronousSerialWorkQueue(AsynchronousOperationListenerProvider.NullListener); var doneEvent = new AutoResetEvent(initialState: false); var actionRan = false; worker.EnqueueBackgroundWork(() => { // Assert.NotNull(SynchronizationContext.Current); Assert.NotSame(_foregroundSyncContext, SynchronizationContext.Current); actionRan = true; doneEvent.Set(); }, GetType().Name + ".TestBackgroundAction", CancellationToken.None); doneEvent.WaitOne(); Assert.True(actionRan); }
private int _isRequestPending; // int for Interlocked public TagComputer( ITextBuffer textBuffer, ClassificationTypeMap typeMap, IAsynchronousOperationListener asyncListener, SyntacticClassificationTaggerProvider taggerProvider) { _textBuffer = textBuffer; _typeMap = typeMap; _taggerProvider = taggerProvider; _workQueue = new AsynchronousSerialWorkQueue(taggerProvider._threadingContext, asyncListener); _workspaceRegistration = Workspace.GetWorkspaceRegistration(textBuffer.AsTextContainer()); _workspaceRegistration.WorkspaceChanged += OnWorkspaceRegistrationChanged; if (this._workspaceRegistration.Workspace != null) { ConnectToWorkspace(this._workspaceRegistration.Workspace); } }
public TagSource( ITextView textViewOpt, ITextBuffer subjectBuffer, AbstractAsynchronousTaggerProvider <TTag> dataSource, IAsynchronousOperationListener asyncListener, IForegroundNotificationService notificationService) { if (dataSource.SpanTrackingMode == SpanTrackingMode.Custom) { throw new ArgumentException("SpanTrackingMode.Custom not allowed.", "spanTrackingMode"); } _subjectBuffer = subjectBuffer; _textViewOpt = textViewOpt; _dataSource = dataSource; _asyncListener = asyncListener; _notificationService = notificationService; _tagSpanComparer = new TagSpanComparer(_dataSource.TagComparer); DebugRecordInitialStackTrace(); _workQueue = new AsynchronousSerialWorkQueue(asyncListener); this.CachedTagTrees = ImmutableDictionary.Create <ITextBuffer, TagSpanIntervalTree <TTag> >(); _eventSource = CreateEventSource(); Connect(); // Kick off a task to immediately compute the initial set of tags. This work should // not be cancellable (except if we get completely released), even if more events come // in. That way we can get the initial set of results for the buffer as quickly as // possible, without kicking the work down the road. var initialTagsCancellationToken = _initialComputationCancellationTokenSource.Token; // Note: we always kick this off to the new UI pump instead of computing tags right // on this thread. The reason for that is that we may be getting created at a time // when the view itself is initializing. As such the view is not in a state where // we want code touching it. RegisterNotification( () => RecomputeTagsForeground(cancellationTokenOpt: initialTagsCancellationToken), delay: 0, cancellationToken: initialTagsCancellationToken); }
public void TestBackgroundAction() { var listener = new AggregateAsynchronousOperationListener(Enumerable.Empty <Lazy <IAsynchronousOperationListener, FeatureMetadata> >(), "Test"); var worker = new AsynchronousSerialWorkQueue(listener); var doneEvent = new AutoResetEvent(initialState: false); var actionRan = false; worker.EnqueueBackgroundWork(() => { // Assert.NotNull(SynchronizationContext.Current); Assert.NotSame(_foregroundSyncContext, SynchronizationContext.Current); actionRan = true; doneEvent.Set(); }, GetType().Name + ".TestBackgroundAction", CancellationToken.None); doneEvent.WaitOne(); Assert.True(actionRan); }
public ProjectionBufferService( IProjectionBufferFactoryService projectionBufferFactoryService, IContentTypeRegistryService contentTypeRegistryService, IForegroundNotificationService foregroundNotificationService, IAsynchronousOperationListener listener, Workspace workspace) { _projectionBufferFactoryService = projectionBufferFactoryService; _listener = listener; _foregroundNotificationService = foregroundNotificationService; _workspace = workspace; _workspace.DocumentOpened += OnDocumentChanged; _workspace.DocumentChanged += OnDocumentChanged; _hlslContentType = contentTypeRegistryService.GetContentType(LanguageNames.Hlsl); _workQueue = new AsynchronousSerialWorkQueue(new AsynchronousOperationListener()); }
public void TestBackgroundCancel1() { // Ensure that we can cancel a background action. var listener = new AggregateAsynchronousOperationListener(Enumerable.Empty <Lazy <IAsynchronousOperationListener, FeatureMetadata> >(), "Test"); var worker = new AsynchronousSerialWorkQueue(listener); var taskRunningEvent = new AutoResetEvent(false); var cancelEvent = new AutoResetEvent(false); var doneEvent = new AutoResetEvent(false); var source = new CancellationTokenSource(); var cancellationToken = source.Token; var actionRan = false; worker.EnqueueBackgroundWork(() => { actionRan = true; Assert.NotSame(_foregroundSyncContext, SynchronizationContext.Current); Assert.False(cancellationToken.IsCancellationRequested); taskRunningEvent.Set(); cancelEvent.WaitOne(); Assert.True(cancellationToken.IsCancellationRequested); doneEvent.Set(); }, "Test", source.Token); taskRunningEvent.WaitOne(); source.Cancel(); cancelEvent.Set(); doneEvent.WaitOne(); Assert.True(actionRan); }
internal TestAccessor(AsynchronousSerialWorkQueue asynchronousSerialWorkQueue) { _asynchronousSerialWorkQueue = asynchronousSerialWorkQueue; }
public TagSource( ITextView textViewOpt, ITextBuffer subjectBuffer, AbstractAsynchronousTaggerProvider <TTag> dataSource, IAsynchronousOperationListener asyncListener, IForegroundNotificationService notificationService) : base(dataSource.ThreadingContext) { this.AssertIsForeground(); if (dataSource.SpanTrackingMode == SpanTrackingMode.Custom) { throw new ArgumentException("SpanTrackingMode.Custom not allowed.", "spanTrackingMode"); } _subjectBuffer = subjectBuffer; _textViewOpt = textViewOpt; _dataSource = dataSource; _asyncListener = asyncListener; _notificationService = notificationService; _batchChangeTokenSource = new CancellationTokenSource(); _batchChangeNotifier = new BatchChangeNotifier( dataSource.ThreadingContext, subjectBuffer, asyncListener, notificationService, NotifyEditorNow, _batchChangeTokenSource.Token); DebugRecordInitialStackTrace(); _workQueue = new AsynchronousSerialWorkQueue(ThreadingContext, asyncListener); this.CachedTagTrees = ImmutableDictionary.Create <ITextBuffer, TagSpanIntervalTree <TTag> >(); _eventSource = CreateEventSource(); Connect(); // Start computing the initial set of tags immediately. We want to get the UI // to a complete state as soon as possible. ComputeInitialTags(); return; void Connect() { this.AssertIsForeground(); _eventSource.Changed += OnEventSourceChanged; if (_dataSource.TextChangeBehavior.HasFlag(TaggerTextChangeBehavior.TrackTextChanges)) { _subjectBuffer.Changed += OnSubjectBufferChanged; } if (_dataSource.CaretChangeBehavior.HasFlag(TaggerCaretChangeBehavior.RemoveAllTagsOnCaretMoveOutsideOfTag)) { if (_textViewOpt == null) { throw new ArgumentException( nameof(_dataSource.CaretChangeBehavior) + " can only be specified for an " + nameof(IViewTaggerProvider)); } _textViewOpt.Caret.PositionChanged += OnCaretPositionChanged; } // Tell the interaction object to start issuing events. _eventSource.Connect(); } }
public void TestBackgroundCancelOneAction() { // Ensure that when a background action is cancelled the next // one starts (if it has a different cancellation token). var worker = new AsynchronousSerialWorkQueue(AsynchronousOperationListenerProvider.NullListener); var taskRunningEvent = new AutoResetEvent(false); var cancelEvent = new AutoResetEvent(false); var doneEvent = new AutoResetEvent(false); var source1 = new CancellationTokenSource(); var source2 = new CancellationTokenSource(); var token1 = source1.Token; var token2 = source2.Token; var action1Ran = false; var action2Ran = false; worker.EnqueueBackgroundWork(() => { action1Ran = true; Assert.NotSame(_foregroundSyncContext, SynchronizationContext.Current); Assert.False(token1.IsCancellationRequested); taskRunningEvent.Set(); cancelEvent.WaitOne(); token1.ThrowIfCancellationRequested(); Assert.True(false); }, "Test", source1.Token); worker.EnqueueBackgroundWork(() => { action2Ran = true; Assert.NotSame(_foregroundSyncContext, SynchronizationContext.Current); Assert.False(token2.IsCancellationRequested); taskRunningEvent.Set(); cancelEvent.WaitOne(); doneEvent.Set(); }, "Test", source2.Token); // Wait for the first task to start. taskRunningEvent.WaitOne(); // Cancel it source1.Cancel(); cancelEvent.Set(); // Wait for the second task to start. taskRunningEvent.WaitOne(); cancelEvent.Set(); // Wait for the second task to complete. doneEvent.WaitOne(); Assert.True(action1Ran); Assert.True(action2Ran); }