Esempio n. 1
0
        protected async Task WaitForIdleAsync(IExpeditableDelaySource expeditableDelaySource)
        {
            while (true)
            {
                if (CancellationToken.IsCancellationRequested)
                {
                    return;
                }

                var diffInMS = Environment.TickCount - _lastAccessTimeInMS;
                if (diffInMS >= BackOffTimeSpanInMS)
                {
                    return;
                }

                // TODO: will safestart/unwarp capture cancellation exception?
                var timeLeft = BackOffTimeSpanInMS - diffInMS;
                if (!await expeditableDelaySource.Delay(TimeSpan.FromMilliseconds(Math.Max(MinimumDelayInMS, timeLeft)), CancellationToken).ConfigureAwait(false))
                {
                    // The delay terminated early to accommodate a blocking operation. Make sure to delay long
                    // enough that low priority (on idle) operations get a chance to be triggered.
                    //
                    // 📝 At the time this was discovered, it was not clear exactly why the delay was needed in order
                    // to avoid live-lock scenarios.
                    await Task.Delay(TimeSpan.FromMilliseconds(10), CancellationToken).ConfigureAwait(false);

                    return;
                }
            }
        }
Esempio n. 2
0
        protected async Task WaitForIdleAsync(IExpeditableDelaySource expeditableDelaySource)
        {
            while (true)
            {
                if (CancellationToken.IsCancellationRequested)
                {
                    return;
                }

                var diff = _timeSinceLastAccess.Elapsed;
                if (diff >= BackOffTimeSpan)
                {
                    return;
                }

                // TODO: will safestart/unwarp capture cancellation exception?
                var timeLeft = BackOffTimeSpan - diff;
                if (!await expeditableDelaySource.Delay(TimeSpan.FromMilliseconds(Math.Max(s_minimumDelay.TotalMilliseconds, timeLeft.TotalMilliseconds)), CancellationToken).ConfigureAwait(false))
                {
                    // The delay terminated early to accommodate a blocking operation. Make sure to yield so low
                    // priority (on idle) operations get a chance to be triggered.
                    //
                    // 📝 At the time this was discovered, it was not clear exactly why the yield (previously delay)
                    // was needed in order to avoid live-lock scenarios.
                    await Task.Yield().ConfigureAwait(false);

                    return;
                }
            }
        }
Esempio n. 3
0
        private async Task StartTimerAsync(bool continueOnCapturedContext)
        {
            do
            {
                // Keep delaying until at least delayInMilliseconds has elapsed since lastSetTime
                if (!await _expeditableDelaySource.Delay(TimeSpan.FromMilliseconds(_delayInMilliseconds), CancellationToken.None).ConfigureAwait(continueOnCapturedContext))
                {
                    // The operation is being expedited.
                    break;
                }
            }while (Environment.TickCount - _lastSetTime < _delayInMilliseconds);

            _taskCompletionSource.SetResult(null);
        }