My application writes a log file (currently using log4net). I'd like to setup a timer and a background worker to read the log file and print its content into some control in my form, while it's being written.
I can't use the FileSystemWatcher class because seems broken: sometimes the event "changed" fires, sometimes do not. And it has an extremely low "pooling rate".
So I created a Timer and a FileSystemWatcher. On the "tick" event of the timer, the background worker does its job.
The question is: how to read only the lines that are added since the last check of the worker?
public LogForm()
{
InitializeComponent();
logWatcherTimer.Start();
}
private void logWatcherTimer_Tick(object sender, EventArgs e)
{
FileInfo log = new FileInfo(@"C:\log.txt");
if(!logWorker.IsBusy) logWorker.RunWorkerAsync(log);
}
private void logWorker_DoWork(object sender, DoWorkEventArgs e)
{
// Read only new lines since last check.
FileInfo log = (FileInfo) e.Argument;
// Here is the main question!
}
EDIT: Code Solution (maybe there is a more elegant way?):
private void logWatherWorker_DoWork(object sender, DoWorkEventArgs e)
{
// retval
string newLines = string.Empty;
FileInfo log = (FileInfo) e.Argument;
// Just skip if log file hasn't changed
if (lastLogLength == log.Length) return;
using (StreamReader stream = new StreamReader(log.FullName))
{
// Set the position to the last log size and read
// all the content added
stream.BaseStream.Position = lastLogLength;
newLines = stream.ReadToEnd();
}
// Keep track of the previuos log length
lastLogLength = log.Length;
// Assign the result back to the worker, to be
// consumed by the form
e.Result = newLines;
}
Check and store the file size each time you read the log, then start your text reader (or whatever you're using) at that location the next time you read.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With