public class Logger { private Queue
queue; private ManualResetEvent manual;
private Thread logThread; /// /// 指定存储文件的路径 /// public static string Path { get; set; }
//私有构造函数,初始化相关对象 使用单例模式 private Logger() { queue = new Queue(); manual = new ManualResetEvent(false); logThread = new Thread(Process); logThread.IsBackground = true; logThread.Start(); } private readonly static Logger logger = new Logger(); private static Logger GetInstance() { return logger; } //不断处理队列中的任务 private void Process() { while (true) { manual.WaitOne();
manual.Reset();
Thread.Sleep(100);
Queue copy; lock (queue) { copy = new Queue(queue); queue.Clear(); foreach (var action in copy) action(); } } } private void ExcuteAction(string log) { string date = DateTime.Now.ToString(); string path; if (!string.IsNullOrEmpty(Path)) path = Path + "log.txt"; else path = "log.txt"; lock(queue) { queue.Enqueue(() => File.AppendAllText(path, log+" : "+date + Environment.NewLine)); } manual.Set(); }
/// /// 将数据写入文件中 /// /// 要写入的数据 public static void WriteLog(string log) { // WriteLog 方法只是向队列中添加任务,执行时间极短,所以使用Task.Run。 Task.Run(() => { GetInstance().ExcuteAction(log); }); }
}
两条线程读写同一个对象,两条线程都lock这个对象 用ManualResetEvent来控制读数据的线程(Thread(Process)) 当写数据的线程(Task.Run)有数据写入时开启读线程工作 这样有可能控制并发,但测试几次,发现几次数据的顺序有误,但没有漏主线程和新线程调用第三次后顺序没错 开Task线程调用顺序完全相反,开始两次也会有些乱!!!!!!!!!!!!