视觉修改
This commit is contained in:
		
							
								
								
									
										112
									
								
								Check.Main/Common/ThreadSafeLogger.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								Check.Main/Common/ThreadSafeLogger.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,112 @@ | ||||
| using System; | ||||
| using System.Collections.Concurrent; | ||||
| using System.Collections.Generic; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading; | ||||
| using System.Threading.Tasks; | ||||
|  | ||||
| namespace Check.Main.Common | ||||
| { | ||||
|     /// <summary> | ||||
|     /// 一个线程安全的、基于队列的日志记录器。 | ||||
|     /// 使用一个独立的后台线程来处理文件写入,避免业务线程阻塞。 | ||||
|     /// </summary> | ||||
|     public static class ThreadSafeLogger | ||||
|     { | ||||
|         // 使用线程安全的队列作为日志消息的缓冲区 | ||||
|         private static readonly BlockingCollection<string> _logQueue = new BlockingCollection<string>(); | ||||
|  | ||||
|         // 日志写入线程 | ||||
|         private static Thread _logWriterThread; | ||||
|  | ||||
|         private static StreamWriter _logFileWriter; | ||||
|  | ||||
|         // 事件,用于将格式化后的日志消息广播给UI等监听者 | ||||
|         public static event Action<string> OnLogMessage; | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 初始化日志记录器,启动后台写入线程。 | ||||
|         /// </summary> | ||||
|         public static void Initialize() | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 string logDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs"); | ||||
|                 Directory.CreateDirectory(logDirectory); | ||||
|  | ||||
|                 string logFileName = $"Log_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.txt"; | ||||
|                 string logFilePath = Path.Combine(logDirectory, logFileName); | ||||
|  | ||||
|                 _logFileWriter = new StreamWriter(logFilePath, append: true, encoding: Encoding.UTF8) { AutoFlush = true }; | ||||
|  | ||||
|                 // 创建并启动后台线程 | ||||
|                 _logWriterThread = new Thread(ProcessLogQueue) | ||||
|                 { | ||||
|                     IsBackground = true, // 设置为后台线程,这样主程序退出时它会自动终止 | ||||
|                     Name = "LogWriterThread" | ||||
|                 }; | ||||
|                 _logWriterThread.Start(); | ||||
|  | ||||
|                 Log("日志系统已初始化。"); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 // 如果初始化失败,尝试通过事件通知UI | ||||
|                 OnLogMessage?.Invoke($"[CRITICAL] 日志系统初始化失败: {ex.Message}"); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 将一条日志消息添加到队列中。这个方法是线程安全的,且执行速度非常快。 | ||||
|         /// </summary> | ||||
|         /// <param name="message">原始日志消息。</param> | ||||
|         public static void Log(string message) | ||||
|         { | ||||
|             string formattedMessage = $"[{DateTime.Now:HH:mm:ss.fff}] {message}"; | ||||
|             _logQueue.Add(formattedMessage); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 后台线程的工作方法。它会持续不断地从队列中取出消息并处理。 | ||||
|         /// </summary> | ||||
|         private static void ProcessLogQueue() | ||||
|         { | ||||
|             // GetConsumingEnumerable会阻塞等待,直到有新的项加入队列或队列被标记为已完成 | ||||
|             foreach (string message in _logQueue.GetConsumingEnumerable()) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     // 1. 写入文件 | ||||
|                     _logFileWriter?.WriteLine(message); | ||||
|  | ||||
|                     // 2. 触发事件,通知UI | ||||
|                     OnLogMessage?.Invoke(message); | ||||
|                 } | ||||
|                 catch | ||||
|                 { | ||||
|                     // 忽略在日志线程本身发生的写入错误 | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 关闭日志记录器,释放资源。 | ||||
|         /// </summary> | ||||
|         public static void Shutdown() | ||||
|         { | ||||
|             Log("日志系统正在关闭..."); | ||||
|  | ||||
|             // 标记队列不再接受新的项目。这会让ProcessLogQueue中的循环在处理完所有剩余项后自然结束。 | ||||
|             _logQueue.CompleteAdding(); | ||||
|  | ||||
|             // 等待日志线程处理完所有剩余的日志,最多等待2秒 | ||||
|             _logWriterThread?.Join(2000); | ||||
|  | ||||
|             // 关闭文件流 | ||||
|             _logFileWriter?.Close(); | ||||
|             _logFileWriter?.Dispose(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user