作者热门文章
- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
以下是否是实现相当简单的线程安全日志记录类的正确方法?
我知道我从未明确关闭 TextWriter
,这会是个问题吗?
当我最初使用 TextWriter.Synchronized
方法时,它似乎没有工作,直到我在静态构造函数中初始化它并将它设为只读,如下所示:
public static class Logger
{
static readonly TextWriter tw;
static Logger()
{
tw = TextWriter.Synchronized(File.AppendText(SPath() + "\\Log.txt"));
}
public static string SPath()
{
return ConfigManager.GetAppSetting("logPath");
}
public static void Write(string logMessage)
{
try
{
Log(logMessage, tw);
}
catch (IOException e)
{
tw.Close();
}
}
public static void Log(string logMessage, TextWriter w)
{
w.WriteLine("{0} {1}", DateTime.Now.ToLongTimeString(),
DateTime.Now.ToLongDateString());
w.WriteLine(" :");
w.WriteLine(" :{0}", logMessage);
w.WriteLine("-------------------------------");
// Update the underlying file.
w.Flush();
}
}
最佳答案
我将在这里采用与其他答案完全不同的方法,并假设您真的想学习如何编写更好的线程感知代码,而不是从我们这里寻找第 3 方建议(即使您实际上可能最终使用一个。)
正如其他人所说,您正在创建线程安全的 TextWriter
这意味着对 WriteLine 的调用是线程安全的,这并不意味着对 WriteLine
将作为原子操作执行。我的意思是不能保证四个 WriteLine 调用会按顺序发生。您可能有线程安全的 TextWriter
,但没有线程安全的 Logger.Log
方法 ;) 为什么?因为在这四个调用期间的任何时候,另一个线程可能决定也调用 Log
。这意味着您的 WriteLine
调用将不同步。解决这个问题的方法是使用像这样的 lock
语句:
private static readonly object _syncObject = new object();
public static void Log(string logMessage, TextWriter w) {
// only one thread can own this lock, so other threads
// entering this method will wait here until lock is
// available.
lock(_syncObject) {
w.WriteLine("{0} {1}", DateTime.Now.ToLongTimeString(),
DateTime.Now.ToLongDateString());
w.WriteLine(" :");
w.WriteLine(" :{0}", logMessage);
w.WriteLine("-------------------------------");
// Update the underlying file.
w.Flush();
}
}
所以,现在您有一个线程安全的 TextWriter
和一个线程安全的 Logger
。
有道理吗?
关于c# - 线程安全日志类实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6195084/
我是一名优秀的程序员,十分优秀!