private void NotifyEditors(NormalizedSnapshotSpanCollection changes, TaggerDelay delay)
            {
                _tagSource.AssertIsForeground();

                if (changes.Count == 0)
                {
                    // nothing to do.
                    return;
                }

                if (delay == TaggerDelay.NearImmediate)
                {
                    // if delay is immediate, we let notifier knows about the change right away
                    _batchChangeNotifier.EnqueueChanges(changes);
                    return;
                }

                // if delay is anything more than that, we let notifier knows about the change after given delay
                // event notification is only cancellable when disposing of the tagger.
                _tagSource.RegisterNotification(
                    () => _batchChangeNotifier.EnqueueChanges(changes),
                    (int)delay.ComputeTimeDelay(_subjectBuffer).TotalMilliseconds,
                    _cancellationTokenSource.Token
                    );
            }
Exemple #2
0
 public void EnqueueWork(
     Func <Task> workAsync,
     TaggerDelay delay,
     IAsyncToken asyncToken,
     CancellationToken cancellationToken)
 {
     lock (this)
     {
         _eventWorkQueue = _eventWorkQueue.ContinueWithAfterDelayFromAsync(
             _ => workAsync(),
             cancellationToken,
             (int)delay.ComputeTimeDelay().TotalMilliseconds,
             TaskContinuationOptions.None,
             TaskScheduler.Default).CompletesAsyncOperation(asyncToken);
     }
 }
            private void EnqueueNotificationRequest(TaggerDelay delay)
            {
                AssertIsForeground();

                if (_notificationRequestEnqueued)
                {
                    // we already have a pending task to update the UI.  No need to do anything at this
                    // point.
                    return;
                }

                var currentTick = Environment.TickCount;

                if (
                    Math.Abs(currentTick - _lastReportTick)
                    > TaggerDelay.NearImmediate.ComputeTimeDelay(_subjectBuffer).TotalMilliseconds
                    )
                {
                    _lastReportTick = currentTick;
                    this.NotifyEditor();
                }
                else
                {
                    // enqueue a task to update the UI with all the changed spans at some time in the
                    // future.
                    _notificationRequestEnqueued = true;

                    // Note: this operation is uncancellable.  We already updated our internal state in
                    // RecomputeTags. We must eventually notify the editor about these changes so that the
                    // UI reaches parity with our internal model.  Also, if we cancel it, then
                    // 'reportTagsScheduled' will stay 'true' forever and we'll never notify the UI.
                    _notificationService.RegisterNotification(
                        () =>
                    {
                        AssertIsForeground();

                        // First, clear the flag.  That way any new changes we hear about will enqueue a task
                        // to run at a later point.
                        _notificationRequestEnqueued = false;
                        this.NotifyEditor();
                    },
                        (int)delay.ComputeTimeDelay(_subjectBuffer).TotalMilliseconds,
                        _listener.BeginAsyncOperation("EnqueueNotificationRequest"),
                        _cancellationToken
                        );
                }
            }
        // We may get a flurry of 'Notify' calls if we've enqueued a lot of work and it's now just
        // completed.  Batch up all the notifications so we can tell the editor about them at the
        // same time.
        private void EnqueueNotificationRequest(
            TaggerDelay delay)
        {
            AssertIsForeground();

            if (_notificationRequestEnqueued)
            {
                // we already have a pending task to update the UI.  No need to do anything at this
                // point.
                return;
            }

            var currentTick = Environment.TickCount;
            if (Math.Abs(currentTick - _lastReportTick) > _throttleDelay.ComputeTimeDelay(_subjectBuffer))
            {
                _lastReportTick = currentTick;
                this.NotifyEditor();
            }
            else
            {
                // enqueue a task to update the UI with all the changed spans at some time in the
                // future.
                _notificationRequestEnqueued = true;

                // Note: this operation is uncancellable.  We already updated our internal state in
                // RecomputeTags. We must eventually notify the editor about these changes so that the
                // UI reaches parity with our internal model.  Also, if we cancel it, then
                // 'reportTagsScheduled' will stay 'true' forever and we'll never notify the UI.
                _notificationService.RegisterNotification(() =>
                {
                    AssertIsForeground();

                    // First, clear the flag.  That way any new changes we hear about will enqueue a task
                    // to run at a later point.
                    _notificationRequestEnqueued = false;
                    this.NotifyEditor();
                }, delay.ComputeTimeDelay(_subjectBuffer), _listener.BeginAsyncOperation("EnqueueNotificationRequest"));
            }
        }