我有一个简单的简单日志类,它是静态的。但是,它绝对不是线程安全的,因为每次调用都会尝试写入同一个文件。我得到以下例外:
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)
...
使线程安全的最佳方法是什么?
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);
}
}
作为日志记录功能,我希望能够从我的代码的许多不同部分访问它(因此,为什么我选择它作为静态)。但是,我想象的是为了使它成为线程安全的,我总是要将它传递给lock()on一个常见的对象,我认为这违背了静态函数的目的。或者情况不是这样吗?
答案 0 :(得分:19)
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);
}
}
}
答案 1 :(得分:2)
在LogMessageToFile方法中,您需要一个锁来阻止多线程访问:
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);
}
}