/// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        protected virtual async Task OnTick()
        {
            try
            {
                int count;
                do
                {
                    count = 0;

                    using (var bookmarkFile = _fileSet.OpenBookmarkFile())
                    {
                        var position = bookmarkFile.TryReadBookmark();
                        var files    = _fileSet.GetBufferFiles();

                        if (position.File == null || !IOFile.Exists(position.File))
                        {
                            position = new FileSetPosition(0, files.FirstOrDefault());
                        }

                        TPayload payload;
                        if (position.File == null)
                        {
                            payload = _payloadReader.GetNoPayload();
                            count   = 0;
                        }
                        else
                        {
                            payload = _payloadReader.ReadPayload(_batchPostingLimit, _eventBodyLimitBytes, ref position, ref count, position.File);
                        }

                        if (count > 0 || _controlledSwitch.IsActive && _nextRequiredLevelCheckUtc < DateTime.UtcNow)
                        {
                            _nextRequiredLevelCheckUtc = DateTime.UtcNow.Add(RequiredLevelCheckInterval);

                            var result = await _logClient.SendPayloadAsync(payload).ConfigureAwait(false);

                            if (result.Success)
                            {
                                _connectionSchedule.MarkSuccess();
                                if (result.InvalidResult != null)
                                {
                                    DumpInvalidPayload(result.InvalidResult.StatusCode, result.InvalidResult.Content, result.InvalidResult.BadPayLoad);
                                }
                                bookmarkFile.WriteBookmark(position);
                            }
                            else
                            {
                                _connectionSchedule.MarkFailure();
                                if (_bufferSizeLimitBytes.HasValue)
                                {
                                    _fileSet.CleanUpBufferFiles(_bufferSizeLimitBytes.Value, 2);
                                }

                                break;
                            }
                        }
                        else if (position.File == null)
                        {
                            break;
                        }
                        else
                        {
                            // For whatever reason, there's nothing waiting to send. This means we should try connecting again at the
                            // regular interval, so mark the attempt as successful.
                            _connectionSchedule.MarkSuccess();

                            // Only advance the bookmark if no other process has the
                            // current file locked, and its length is as we found it.
                            if (files.Length == 2 && files.First() == position.File &&
                                FileIsUnlockedAndUnextended(position))
                            {
                                bookmarkFile.WriteBookmark(new FileSetPosition(0, files[1]));
                            }

                            if (files.Length > 2)
                            {
                                // By this point, we expect writers to have relinquished locks
                                // on the oldest file.
                                IOFile.Delete(files[0]);
                            }
                        }
                    }
                } while (count == _batchPostingLimit);
            }
            catch (Exception ex)
            {
                _connectionSchedule.MarkFailure();
                SelfLog.WriteLine("Exception while emitting periodic batch from {0}: {1}", this, ex);

                if (_bufferSizeLimitBytes.HasValue)
                {
                    _fileSet.CleanUpBufferFiles(_bufferSizeLimitBytes.Value, 2);
                }
            }
            finally
            {
                lock (_stateLock)
                {
                    if (!_unloading)
                    {
                        SetTimer();
                    }
                }
            }
        }