如何在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
相关产品推荐
相关产品推荐

