How to make a static class thread safe?

I have a simple simple log, static. However, it is definitely not thread safe, as each call tries to write to the same file. I get these exceptions:

The process cannot access the file 'logfile.txt' because it is being used by another process. at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) ... 

What is the best way to make it thread safe?

 public static class Logger { private static readonly string LOG_FILENAME = "logfile.txt"; private static readonly string LOG_FOLDER = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "App name"); private static readonly string LOG_FULLPATH = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "App name", LOG_FILENAME); public static void LogMessageToFile(string msg) { msg = string.Format("{0:G}: {1}{2}", DateTime.Now, msg, Environment.NewLine); File.AppendAllText(LOG_FULLPATH, msg); } } 

As a registration function, I would like to have access to it from different parts of my code (hence why I chose it as static). However, I imagine that to ensure thread safety, I always need to pass it a common object to block (), which, I think, defeats the purpose of the static function. Or is it not so?

+4
source share
2 answers
 public static class Logger { private static readonly string LOG_FILENAME = "logfile.txt"; private static readonly string LOG_FOLDER = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "App name"); private static readonly string LOG_FULLPATH = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "App name", LOG_FILENAME); private static Object theLock=new Object(); public static void LogMessageToFile(string msg) { msg = string.Format("{0:G}: {1}{2}", DateTime.Now, msg, Environment.NewLine); lock (theLock) { File.AppendAllText(LOG_FULLPATH, msg); } } } 
+17
source

In your LogMessageToFile method, you need a lock to prevent multithreaded access:

 private static Object _mylock = new Object(); public static void LogMessageToFile(string msg) { lock(_mylock) { msg = string.Format("{0:G}: {1}{2}", DateTime.Now, msg, Environment.NewLine); File.AppendAllText(LOG_FULLPATH, msg); } } 
+2
source

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


All Articles