You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 22:25:23