如何在MachineWatcher中调用主窗口函数统一收集错误信息?
问题解答
核心结论
可以直接调用主窗口的函数,但不推荐这么做——这种强耦合设计会让MachineWatcher类依赖主窗口实现,无法单独复用,也会增加测试难度。更合理的做法是通过解耦的方式传递错误信息。
推荐实现方案
方案1:使用事件(Event)
在MachineWatcher中定义错误事件,主窗口订阅该事件,收到事件后更新ListErrors。这种方式是.NET中组件间通信的标准做法,完全解耦两个类。
MachineWatcher类代码:
public class MachineWatcher { // 定义错误事件,参数为错误信息 public event EventHandler<string> ErrorOccurred; // 触发事件的辅助方法 private void RaiseError(string errorMessage) { ErrorOccurred?.Invoke(this, errorMessage); } // 文件监控逻辑示例 public void StartWatching() { try { // 你的FileSystemWatcher初始化及监控逻辑 } catch (Exception ex) { // 构造带机器标识的错误信息 string error = $"[{MachineName}] 监控出错:{ex.Message}"; // 触发事件通知上层 RaiseError(error); } } // 机器标识属性 public string MachineName { get; set; } }
主窗口代码:
// 初始化监控实例列表 List<MachineWatcher> machineWatchers = new List<MachineWatcher>(); // 创建并配置单个监控实例 var watcher = new MachineWatcher { MachineName = "生产线机器01" }; // 订阅错误事件,更新Observable错误列表 watcher.ErrorOccurred += (sender, errorMsg) => { ListErrors.OnNext(errorMsg); }; machineWatchers.Add(watcher); watcher.StartWatching();
方案2:注入错误处理委托(Action)
在MachineWatcher的构造函数中传入一个处理错误的委托,catch块中直接调用该委托。这种方式比事件更轻量,适合简单场景。
MachineWatcher类代码:
public class MachineWatcher { private readonly Action<string> _errorHandler; // 构造函数注入错误处理委托 public MachineWatcher(Action<string> errorHandler) { _errorHandler = errorHandler ?? throw new ArgumentNullException(nameof(errorHandler)); } public void StartWatching() { try { // 你的FileSystemWatcher监控逻辑 } catch (Exception ex) { string error = $"[{MachineName}] 监控出错:{ex.Message}"; // 调用委托传递错误信息 _errorHandler(error); } } public string MachineName { get; set; } }
主窗口代码:
List<MachineWatcher> machineWatchers = new List<MachineWatcher>(); // 创建实例时直接传入错误处理逻辑 var watcher = new MachineWatcher(errorMsg => ListErrors.OnNext(errorMsg)) { MachineName = "生产线机器01" }; machineWatchers.Add(watcher); watcher.StartWatching();
为什么不推荐直接调用主窗口函数?
- 强耦合:
MachineWatcher必须知道主窗口的类型和方法,无法在其他场景复用。 - 线程风险:FileSystemWatcher的事件可能在非UI线程触发,直接调用主窗口UI方法会引发跨线程异常,需要额外处理线程调度。
- 测试困难:无法单独测试
MachineWatcher的错误逻辑,必须依赖主窗口实例。
内容的提问来源于stack exchange,提问作者Siegfried.V
相关产品推荐
相关产品推荐

