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

如何在FileSystemWatcher类变更事件触发错误时通知主窗体?

问题描述

我有一个窗体,调用某类创建FileSystemWatcher,该类会在FileSystemWatcher触发时执行各类操作。当FileSystemWatcher的Changed事件执行过程中发生错误时,我需要通知主窗体出现问题。

我的FileSystemWatcher类代码如下:

internal static class PpsTransactionFileWatcher
{
  private static FileSystemWatcher _watcher;

  public static Suburban.Miscellaneous.Response StartPpsFileWatcher()
  {
    var response = new Suburban.Miscellaneous.Response();
    response.IsSuccess = true;
    response.Message = "Success";

    try
    {
      CreateTrnFileWatcher();
      ProcessTransactionFile();
      return response;
    }
    catch (Exception ex)
    {
      LoggingWrapper.Log("StartPpsFileWatcher", ex.ToString(), ex);
      response.IsSuccess = false;
      response.Message = ex.Message;
      return response;
    }
  }

  private static void CreateTrnFileWatcher()
  {
    try
    {
      _watcher = new FileSystemWatcher
      {
        Path = GlobalSettings.PpsDirectory,
        NotifyFilter = NotifyFilters.LastWrite,
        Filter = GlobalSettings.PpsTransactionFile
      };

      _watcher.Changed += TrnWatcherChanged;
      _watcher.EnableRaisingEvents = true;
    }
    catch (Exception ex)
    {
      LoggingWrapper.Log("CreateTrnFileWatcher", ex.ToString(), ex);
      throw;
    }
  }


  private static void TrnWatcherChanged(object sender, FileSystemEventArgs e)
  {
    try
    {
      _watcher.Changed -= TrnWatcherChanged;
      ProcessTransactionFile();
      _watcher.Changed += TrnWatcherChanged;
    }
    catch (Exception ex)
    {
      LoggingWrapper.Log("TrnWatcherChanged", ex.ToString(), ex);
    }
  }
}

在窗体中我通过以下代码调用该类:

var transresponse = PpsTransactionFileWatcher.StartPpsFileWatcher();

请问如何在变更事件触发后,通知主窗体该类抛出的异常?


解决方案

可以通过在静态类中定义静态事件的方式,让主窗体订阅该事件,当Changed事件中发生异常时触发事件通知窗体。

步骤1:修改PpsTransactionFileWatcher类,添加异常通知事件

在类中新增静态事件用于传递异常信息,然后在TrnWatcherChanged的捕获块中触发该事件:

internal static class PpsTransactionFileWatcher
{
  private static FileSystemWatcher _watcher;
  // 定义静态事件,用于向外通知异常
  public static event EventHandler<Exception> WatcherErrorOccurred;

  public static Suburban.Miscellaneous.Response StartPpsFileWatcher()
  {
    var response = new Suburban.Miscellaneous.Response();
    response.IsSuccess = true;
    response.Message = "Success";

    try
    {
      CreateTrnFileWatcher();
      ProcessTransactionFile();
      return response;
    }
    catch (Exception ex)
    {
      LoggingWrapper.Log("StartPpsFileWatcher", ex.ToString(), ex);
      response.IsSuccess = false;
      response.Message = ex.Message;
      return response;
    }
  }

  private static void CreateTrnFileWatcher()
  {
    try
    {
      _watcher = new FileSystemWatcher
      {
        Path = GlobalSettings.PpsDirectory,
        NotifyFilter = NotifyFilters.LastWrite,
        Filter = GlobalSettings.PpsTransactionFile
      };

      _watcher.Changed += TrnWatcherChanged;
      _watcher.EnableRaisingEvents = true;
    }
    catch (Exception ex)
    {
      LoggingWrapper.Log("CreateTrnFileWatcher", ex.ToString(), ex);
      throw;
    }
  }


  private static void TrnWatcherChanged(object sender, FileSystemEventArgs e)
  {
    try
    {
      _watcher.Changed -= TrnWatcherChanged;
      ProcessTransactionFile();
      _watcher.Changed += TrnWatcherChanged;
    }
    catch (Exception ex)
    {
      LoggingWrapper.Log("TrnWatcherChanged", ex.ToString(), ex);
      // 触发异常通知事件,传递捕获到的异常
      WatcherErrorOccurred?.Invoke(null, ex);
    }
  }
}

步骤2:在主窗体中订阅事件并处理通知

在窗体的初始化逻辑(比如Form_Load事件)中订阅异常事件,注意FileSystemWatcher的事件在非UI线程触发,需要通过Invoke切换到UI线程更新界面:

private void Form1_Load(object sender, EventArgs e)
{
    // 订阅异常通知事件
    PpsTransactionFileWatcher.WatcherErrorOccurred += PpsTransactionFileWatcher_WatcherErrorOccurred;
    // 启动文件监视器
    var transresponse = PpsTransactionFileWatcher.StartPpsFileWatcher();
}

private void PpsTransactionFileWatcher_WatcherErrorOccurred(object sender, Exception e)
{
    // 跨线程访问UI控件必须使用Invoke切换到UI线程
    if (this.InvokeRequired)
    {
        this.Invoke(new Action<object, Exception>(PpsTransactionFileWatcher_WatcherErrorOccurred), sender, e);
        return;
    }
    // 这里处理异常通知,比如弹出提示框
    MessageBox.Show($"文件监视器发生错误:{e.Message}", "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
}

补充优化

  • 如果需要传递更多上下文信息(比如触发异常的文件路径),可以自定义事件参数类:
public class WatcherErrorEventArgs : EventArgs
{
    public Exception Error { get; set; }
    public string TriggerFilePath { get; set; }
}

然后修改事件定义为public static event EventHandler<WatcherErrorEventArgs> WatcherErrorOccurred;,触发时传递参数:

WatcherErrorOccurred?.Invoke(null, new WatcherErrorEventArgs { Error = ex, TriggerFilePath = e.FullPath });
  • 窗体关闭时记得取消订阅事件,避免内存泄漏:
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
    PpsTransactionFileWatcher.WatcherErrorOccurred -= PpsTransactionFileWatcher_WatcherErrorOccurred;
}

内容的提问来源于stack exchange,提问作者SomeoneSpecial

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 00:21:43