Does preventing error block "The process cannot access the file because it is being used by another process"?

Here is my logging function:

public static void WriteLog(string source, string message) { string logFilePath = @"C:\LogFile\log.txt"; using (StreamWriter sw = new StreamWriter(logFilePath, true)) { sw.Write(source + ": :" + message); } } 

But this code sometimes caused me an error:

The process cannot access the file because it is being used by another process.

So, I changed my code a bit, and here is my new code:

 public static void WriteLog(string source, string message) { object _lock = new object(); lock (_lock) { string logFilePath = @"C:\LogFile\log.txt"; using (StreamWriter sw = new StreamWriter(logFilePath, true)) { sw.Write(source + ": :" + message); } } } 

Although I did not receive an error message after using this code. But still, I just wanted to know if it was right to use a lock to prevent such errors due to a deadlock, and if the way I used the lock was correct or not.

+6
source share
2 answers

Using a lock in the second example will not work properly, because you create a new lock object and lock it every time.

What you really need, a wise file looks something like this:

 public static void WriteLog(string source, string message) { string logFilePath = @"C:\LogFile\log.txt"; using (FileStream file = new FileStream(logFilePath,FileMode.Append,FileAccess.Write,FileShare.None)) { StreamWriter writer = new StreamWriter(file); writer.write(source + ": : " + message); file.Flush(); file.Close(); } } 

This should be solely locking the file during recording, but properly closing the file after execution.

This does NOT solve the problem of streaming because two streams can still collide. If one thread locks the file, subsequent requests will not be executed.

To solve this problem with blocking, move the blocking object to statics, which all threads can share and block, for example:

 public static class Logger { private static object locker = new object(); public static void Log(string source, string message) { lock (locker) { string logFilePath = @"C:\LogFile\log.txt"; using (FileStream file = new FileStream(logFilePath,FileMode.Append,FileAccess.Write,FileShare.None)) { StreamWriter writer = new StreamWriter(file); writer.write(source + ": : " + message); writer.Flush(); file.Close(); } } } } 

This will cause subsequent threads to wait until the lock is available before writing to the file, as expected.

Note. Oded remark, although this applies to this method.

+18
source

Use log4net or Launch Application Block in the Enterprise Library . This will certainly help you, as they have already buffered the write to the file.

You can find many patterns on the Internet.

+2
source

Source: https://habr.com/ru/post/924583/


All Articles