private SingleFileInfo GetOrUpdateFileInfo(string fullPath)
        {
            if (this.logFiles.TryGetValue(fullPath, out var logFileInfo))
            {
                if (logFileInfo.IsCurrentlyReading)
                {
                    return(logFileInfo);
                }

                var createDate = File.GetCreationTimeUtc(fullPath);
                if (logFileInfo.CreateDate != createDate)
                {
                    logFileInfo.Dispose();
                    logFileInfo = new SingleFileInfo(fullPath);
                    this.logFiles.AddOrUpdate(fullPath, logFileInfo, (k, v) => logFileInfo);

                    Console.WriteLine($"Reload stream for {fullPath} with creation date {logFileInfo.CreateDate.ToString()}");
                }
            }
            else
            {
                logFileInfo = new SingleFileInfo(fullPath);
                logFiles.TryAdd(fullPath, logFileInfo);
                Console.WriteLine($"Create stream for {fullPath}");
            }
            return(logFileInfo);
        }
        private void ReadFile(string fullPath)
        {
            SingleFileInfo logFileInfo = null;

            lock (@lock)
            {
                try
                {
                    logFileInfo = GetOrUpdateFileInfo(fullPath);
                    if (logFileInfo.IsCurrentlyReading)
                    {
                        return;
                    }
                    logFileInfo.IsCurrentlyReading = true;
                }
                catch (FileNotFoundException)
                {
                    return; // sometimes file rotate and does not at this moment
                }
            }

            try
            {
                var    streamReader = logFileInfo.StreamReader;
                string line         = streamReader.ReadLine();
                while (line != null)
                {
                    eventCount++;
                    OnFile(fullPath, line);
                    line = streamReader.ReadLine();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error while reading {fullPath}");
                throw ex;
            }
            finally
            {
                logFileInfo.IsCurrentlyReading = false;
                if (logFileInfo.CloseFileAfterRead)
                {
                    logFileInfo.Dispose();
                }
            }
        }