wpf 如何使静态类线程安全?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16533285/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I make a static class thread-safe?
提问by Doug
I have a simple simple logging class that is static. However, it's definitely not thread safe as every call attempts 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 logging function, I would like to be able to access it from many different parts of my code (hence, why I chose it to be static). However, I'm imagining that to make it thread safe, I'll always have to pass it a common object to lock() on, which I think defeats the purpose of a static function. Or is that not the case?
作为一个日志功能,我希望能够从我的代码的许多不同部分访问它(因此,为什么我选择它是静态的)。但是,我认为为了使其线程安全,我总是必须将一个公共对象传递给 lock() ,我认为这违背了静态函数的目的。或者事实并非如此?
回答by Eugen Rieck
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);
}
}
}
回答by Gisway
In your LogMessageToFile method, you need a lock to prevent multi-thread accessing:
在你的 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);
}
}

