示例#1
0
        /// <inheritdoc />
        protected override TimeSpan RunOnce(CancellationToken token)
        {
            bool performedWork = false;

            LogFileSection section;

            while (_pendingModifications.TryDequeue(out section) && !token.IsCancellationRequested)
            {
                if (section.IsReset)
                {
                    Clear();
                    _lastLogEntry.Clear();
                    _currentSourceIndex = 0;
                }
                else if (section.IsInvalidate)
                {
                    LogLineIndex startIndex = section.Index;
                    _fullSourceSection = new LogFileSection(0, (int)startIndex);

                    if (_currentSourceIndex > _fullSourceSection.LastIndex)
                    {
                        _currentSourceIndex = (int)section.Index;
                    }

                    Invalidate(_currentSourceIndex);
                    RemoveInvalidatedLines(_lastLogEntry, _currentSourceIndex);
                }
                else
                {
                    _fullSourceSection = LogFileSection.MinimumBoundingLine(_fullSourceSection, section);
                }

                performedWork = true;
            }

            if (!_fullSourceSection.IsEndOfSection(_currentSourceIndex))
            {
                int remaining   = _fullSourceSection.Index + _fullSourceSection.Count - _currentSourceIndex;
                int nextCount   = Math.Min(remaining, BatchSize);
                var nextSection = new LogFileSection(_currentSourceIndex, nextCount);
                _source.GetSection(nextSection, _buffer);

                for (int i = 0; i < nextCount; ++i)
                {
                    if (token.IsCancellationRequested)
                    {
                        break;
                    }

                    LogLine line = _buffer[i];
                    if (_lastLogEntry.Count == 0 || _lastLogEntry[0].LogEntryIndex == line.LogEntryIndex)
                    {
                        TryAddLogLine(line);
                    }
                    else if (line.LogEntryIndex != _lastLogEntry[0].LogEntryIndex)
                    {
                        TryAddLogEntry(_lastLogEntry);
                        _lastLogEntry.Clear();
                        TryAddLogLine(line);
                    }
                }

                _currentSourceIndex += nextCount;
            }

            if (_fullSourceSection.IsEndOfSection(_currentSourceIndex))
            {
                TryAddLogEntry(_lastLogEntry);
                Listeners.OnRead(_indices.Count);

                if (_source.EndOfSourceReached)
                {
                    SetEndOfSourceReached();
                }
            }

            if (performedWork)
            {
                return(TimeSpan.Zero);
            }

            return(_maximumWaitTime);
        }