WPF通用日志添加函数开发:同步Log4Net与ObservableCollection日志
没问题,我给你整理一个干净利落的解决方案,一次性搞定Log4Net日志写入和ObservableCollection的更新!
核心思路
我们要封装一个静态日志助手类,把Log4Net的日志记录逻辑和ObservableCollection的更新逻辑整合到一起,对外暴露和Log4Net用法一致的快捷方法(比如Info、Error),这样你只需要调用一次助手类的方法,就能同时完成两个操作。
完整代码实现
首先确保你已经定义了LogEntry类(如果还没完善,可以参考下面的示例):
public class LogEntry { public Level Level { get; set; } public string Message { get; set; } public string Source { get; set; } public DateTime Timestamp { get; set; } // 可以根据需求添加更多属性,比如线程ID、异常详情等 }
然后是核心的日志助手类:
using log4net; using log4net.Core; using System; using System.Collections.ObjectModel; using System.Windows; public static class LogHelper { // 初始化Log4Net日志实例,默认取当前类作为日志源 private static readonly ILog _log = LogManager.GetLogger(typeof(LogHelper)); // 全局可观测日志集合,确保初始化完成 public static ObservableCollection<LogEntry> LogEntries { get; set; } = new ObservableCollection<LogEntry>(); // 私有核心方法:统一处理日志记录和集合更新 private static void Log(Level level, string message, string source = null, Exception ex = null) { // 第一步:调用Log4Net写入文本日志 switch (level) { case Level.Info: if (ex == null) _log.Info(message); else _log.Info(message, ex); break; case Level.Debug: if (ex == null) _log.Debug(message); else _log.Debug(message, ex); break; case Level.Warn: if (ex == null) _log.Warn(message); else _log.Warn(message, ex); break; case Level.Error: if (ex == null) _log.Error(message); else _log.Error(message, ex); break; case Level.Fatal: if (ex == null) _log.Fatal(message); else _log.Fatal(message, ex); break; default: _log.Info(message); break; } // 第二步:更新ObservableCollection,确保在UI线程操作 if (LogEntries != null && Application.Current != null) { Application.Current.Dispatcher.Invoke(() => { var logEntry = new LogEntry { Level = level, Message = ex == null ? message : $"{message}\n异常详情:{ex.ToString()}", Source = source ?? _log.Logger.Name, // 默认用Log4Net的日志源名称 Timestamp = DateTime.Now }; LogEntries.Add(logEntry); }); } } // 对外暴露的快捷方法,和Log4Net用法保持一致 public static void Info(string message, string source = null) { Log(Level.Info, message, source); } public static void Info(string message, Exception ex, string source = null) { Log(Level.Info, message, source, ex); } public static void Debug(string message, string source = null) { Log(Level.Debug, message, source); } public static void Warn(string message, string source = null) { Log(Level.Warn, message, source); } public static void Error(string message, string source = null) { Log(Level.Error, message, source); } public static void Error(string message, Exception ex, string source = null) { Log(Level.Error, message, source, ex); } public static void Fatal(string message, string source = null) { Log(Level.Fatal, message, source); } }
使用示例
现在你只需要替换原来的log.Info("My message"),改成调用助手类的方法即可:
// 普通信息日志 LogHelper.Info("用户登录成功"); // 带自定义日志源的日志 LogHelper.Info("加载配置文件完成", "AppConfigService"); // 记录异常日志 try { // 你的业务代码 } catch (Exception ex) { LogHelper.Error("加载数据失败", ex, "DataService"); }
关键注意点
- Log4Net配置:确保你的项目已经正确配置了Log4Net(比如App.config/Web.config里的输出到txt文件的配置),助手类里的
_log实例才能正常工作。 - UI线程安全:用
Application.Current.Dispatcher.Invoke确保ObservableCollection的修改在UI线程执行,避免绑定UI时出现跨线程异常。 - 集合初始化:如果
LogEntries在App启动时还没初始化,记得在App.xaml.cs的OnStartup方法里提前初始化:LogHelper.LogEntries = new ObservableCollection<LogEntry>();
内容的提问来源于stack exchange,提问作者user979033
相关产品推荐
相关产品推荐

