在一个控制台程序中加了一个简单的日志记录,用来在控制台输出的同时保存到文件中。
为了防止影响记录的时间点,把写文件的方法放到异步线程中,但是发现会冲突,于是加了锁,先把消息放进队列,然后在写文件时出队列并记录。
代码如下:
为了防止影响记录的时间点,把写文件的方法放到异步线程中,但是发现会冲突,于是加了锁,先把消息放进队列,然后在写文件时出队列并记录。
代码如下:
public class Logger { private static string path = @"xxxxxxxxx"; private static readonly object locker = new object(); private static Queue<string> logQueue = new Queue<string>(); public static void Log(string message, params object[] objs) { string msg = string.Format(message, objs); string log = string.Format("{0:HH:MM:ss.fff} - {1}", DateTime.Now, msg); Console.WriteLine(log); Logger.logQueue.Enqueue(log); Task.Factory.StartNew(Logger.WriteToFile); } public static void Clear() { Task.Factory.StartNew(Logger.ClearLogFile); } private static void WriteToFile() { lock (Logger.locker) { if (Logger.logQueue.Count > 0) { string msg = Logger.logQueue.Dequeue(); using (TextWriter writer = new StreamWriter(Logger.path, true)) { writer.WriteLine(msg); writer.Close(); } } } } private static void ClearLogFile() { lock (Logger.locker) { using (TextWriter writer = new StreamWriter(Logger.path, false)) { writer.Write(""); writer.Close(); } } } }
发现有一个问题就是,队列这里有时候会抛出一个异常:
错误抛出时,本人看了下发现队列的长度是0,所以很不解,想问下具体是个什么原因。
想本人用Hashtable实现一个队列,避免这种情况。
解决方案
20
晕死!
要想管理一段代码只有一个线程进入,只要写 lock 同步语句,例如
要想管理一段代码只有一个线程进入,只要写 lock 同步语句,例如
private static lockFlag = new object(); void log(string abc) { ...... 不需要互斥的部分 lock(lockFlag) { ....... 需要互斥的部分 } .....不需要互斥的部分 }
扯到“队列”上,都是15年前 java 的某些“怪异模式”的书籍中传播的猫冰。
20
删除“队列”这种误区,你扔掉了一多半代码,什么bug 代码都扔掉了。
只要是动不动就以为编程模式是“队列”地、“生产者-消费者模式”地想法,本人相信你应该仔细反思一下,是不是本人脑子里的 90% 的相关的东西都是这样的有着多余的模式概念。
只要是动不动就以为编程模式是“队列”地、“生产者-消费者模式”地想法,本人相信你应该仔细反思一下,是不是本人脑子里的 90% 的相关的东西都是这样的有着多余的模式概念。