I have a windows service writes its log in a text file in a simple format.
Now, I'm going to create a small application to read the service's log and shows both the existing log and the added one as live view.
The problem is that the service locks the text file for adding the new lines and at the same time the viewer application locks the file for reading.
The Service Code:
void WriteInLog(string logFilePath, data) { File.AppendAllText(logFilePath, string.Format("{0} : {1}\r\n", DateTime.Now, data)); }
The viewer Code:
int index = 0; private void Form1_Load(object sender, EventArgs e) { try { using (StreamReader sr = new StreamReader(logFilePath)) { while (sr.Peek() >= 0) // reading the old data { AddLineToGrid(sr.ReadLine()); index++; } sr.Close(); } timer1.Start(); } catch (Exception ex) { MessageBox.Show(ex.Message); } } private void timer1_Tick(object sender, EventArgs e) { using (StreamReader sr = new StreamReader(logFilePath)) { // skipping the old data, it has read in the Form1_Load event handler for (int i = 0; i < index ; i++) sr.ReadLine(); while (sr.Peek() >= 0) // reading the live data if exists { string str = sr.ReadLine(); if (str != null) { AddLineToGrid(str); index++; } } sr.Close(); } }
Is there any problem in my code in reading and writing way?
How to solve the problem?
The StreamReader locks a text file whilst it is reading it.
ReadLines() will lock the file until it finishes. Answer should represent solution or at least should seem to be pointing toward that direction.
You need to make sure that both the service and the reader open the log file non-exclusively. Try this:
For the service - the writer in your example - use a FileStream
instance created as follows:
var outStream = new FileStream(logfileName, FileMode.Open, FileAccess.Write, FileShare.ReadWrite);
For the reader use the same but change the file access:
var inStream = new FileStream(logfileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
Also, since FileStream
implements IDisposable
make sure that in both cases you consider using a using
statement, for example for the writer:
using(var outStream = ...) { // using outStream here ... }
Good luck!
Explicit set up the sharing mode while reading the text file.
using (FileStream fs = new FileStream(logFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using (StreamReader sr = new StreamReader(fs)) { while (sr.Peek() >= 0) // reading the old data { AddLineToGrid(sr.ReadLine()); index++; } } }
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