Пример #1
0
        protected override async Task <IQueueEntry <T> > DequeueImplAsync(CancellationToken linkedCancellationToken)
        {
            _logger.Trace("Queue {type} dequeuing item...", _options.Name);
            _logger.Trace("Queue count: {0}", _queue.Count);

            while (_queue.Count == 0 && !linkedCancellationToken.IsCancellationRequested)
            {
                _logger.Trace("Waiting to dequeue item...");
                var sw = Stopwatch.StartNew();

                try {
                    await _autoResetEvent.WaitAsync(GetDequeueCanncellationToken(linkedCancellationToken)).AnyContext();
                } catch (OperationCanceledException) { }

                sw.Stop();
                _logger.Trace("Waited for dequeue: {0}", sw.Elapsed.ToString());
            }

            if (_queue.Count == 0)
            {
                return(null);
            }

            _logger.Trace("Dequeue: Attempt");
            if (!_queue.TryDequeue(out QueueEntry <T> info) || info == null)
            {
                return(null);
            }

            info.Attempts++;
            info.DequeuedTimeUtc = SystemClock.UtcNow;

            if (!_dequeued.TryAdd(info.Id, info))
            {
                throw new Exception("Unable to add item to the dequeued list.");
            }

            Interlocked.Increment(ref _dequeuedCount);
            _logger.Trace("Dequeue: Got Item");

            var entry = new QueueEntry <T>(info.Id, info.Value.DeepClone(), this, info.EnqueuedTimeUtc, info.Attempts);
            await entry.RenewLockAsync();

            await OnDequeuedAsync(entry).AnyContext();

            ScheduleNextMaintenance(SystemClock.UtcNow.Add(_options.WorkItemTimeout));

            return(entry);
        }
Пример #2
0
        protected override async Task <IQueueEntry <T> > DequeueImplAsync(CancellationToken linkedCancellationToken)
        {
            bool isTraceLogLevelEnabled = _logger.IsEnabled(LogLevel.Trace);

            if (isTraceLogLevelEnabled)
            {
                _logger.LogTrace("Queue {Name} dequeuing item... Queue count: {Count}", _options.Name, _queue.Count);
            }

            while (_queue.Count == 0 && !linkedCancellationToken.IsCancellationRequested)
            {
                if (isTraceLogLevelEnabled)
                {
                    _logger.LogTrace("Waiting to dequeue item...");
                }
                var sw = Stopwatch.StartNew();

                try {
                    using (var timeoutCancellationTokenSource = new CancellationTokenSource(10000))
                        using (var dequeueCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(linkedCancellationToken, timeoutCancellationTokenSource.Token)) {
                            await _autoResetEvent.WaitAsync(dequeueCancellationTokenSource.Token).AnyContext();
                        }
                } catch (OperationCanceledException) { }

                sw.Stop();
                if (isTraceLogLevelEnabled)
                {
                    _logger.LogTrace("Waited for dequeue: {Elapsed:g}", sw.Elapsed);
                }
            }

            if (_queue.Count == 0)
            {
                return(null);
            }

            if (isTraceLogLevelEnabled)
            {
                _logger.LogTrace("Dequeue: Attempt");
            }
            if (!_queue.TryDequeue(out var info) || info == null)
            {
                return(null);
            }

            info.Attempts++;
            info.DequeuedTimeUtc = SystemClock.UtcNow;

            if (!_dequeued.TryAdd(info.Id, info))
            {
                throw new Exception("Unable to add item to the dequeued list.");
            }

            Interlocked.Increment(ref _dequeuedCount);
            if (isTraceLogLevelEnabled)
            {
                _logger.LogTrace("Dequeue: Got Item");
            }

            var entry = new QueueEntry <T>(info.Id, info.Value.DeepClone(), this, info.EnqueuedTimeUtc, info.Attempts);
            await entry.RenewLockAsync();

            await OnDequeuedAsync(entry).AnyContext();

            ScheduleNextMaintenance(SystemClock.UtcNow.Add(_options.WorkItemTimeout));

            return(entry);
        }