是否可以在C#类中为多个计时器设置一个Exception处理程序?

我有一个C#程序,它运行一个系统托盘应用程序 – 在后台传输/移动/创建/编辑文件。

如果用户手册删除了程序正在使用的文件,则有很多exception处理和循环处理可以防止程序崩溃/卡住。

不幸的是,程序运行的计算机之一是程序崩溃。 计算机很难获得,并且无法加载调试软件(它是一台没有网络访问权限的嵌入式PC)。

我已经尝试找到崩溃的原因(例如未处理的exeption)但是没有找到任何东西,并且无法访问PC,因为它位于远程位置。

我希望找到一种方法来使用AppDomain / UnhandledExceptionEventHandler来捕获所有未处理的exception并将其记录下来进行诊断。 但是,我(在故意)在类“DoSomething.class”中的办公室中创建的exception正在崩溃WinForm应用程序而不是记录exception错误。

我的代码是:

//Current domain for the unhandled exception handling AppDomain currentDomain; [SecurityPermission(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlAppDomain)] public MainForm() { InitializeComponent(); currentDomain = AppDomain.CurrentDomain; currentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler); CreateTimer.Interval = Settings.Default.CreateTimer; CreateTimer.Start(); RunCopyProtocol(); ChangeFilesTimer.Interval = 10000; ChangeFilesTimer.Start(); RunChangeFiles(); throw new Exception("ABC"); } public void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args) { try { Exception ex = (Exception)args.ExceptionObject; SetLabel(ex); } finally { } } private string SetLabel(Exception ex) { String str; str = ex.Message; Label1.Text = str; return str; } private void ChangeFilesTimer_Tick(object sender, EventArgs e) { RunChangeFiles(); throw new Exception("2"); } 

为什么抛出新exception不会调用未处理的exception错误? 我如何使用AppDomain来获取未处理的exception处理程序来处理RunChangeFiles中的这个exception/exception?

AppDomain上的代码基于MSDN示例

如果您的计时器是System.Timers.Timer ,MSDN会在此处记录原因:

Timer组件捕获并抑制事件处理程序为Elapsed事件抛出的所有exception。

看看这个类似的问题: 如何获得Timer Elapsed事件中发生的exception?

您必须捕获已过滤处理程序中抛出的exception,并在ThreadPool线程上重新抛出它们。

使用上面的代码并扩展引用问题的答案:

 private void ChangeFilesTimer_Tick(object sender, EventArgs e) { try { RunChangeFiles(); } catch (Exception ex) { ThreadPool.QueueUserWorkItem( _ => { throw new Exception("Exception on timer thread.", ex); }); } } 

如果您的计时器是System.Windows.Forms.Timer那么您将需要挂钩Application.ThreadException事件来处理未处理的exception。

在调用Application.Run()之前订阅此事件。


在重新抛出exception之前,您还可以在本地exception处理块中处理Exception日志记录。

 try { /// ... } catch (Exception ex) { if (ex is ArgumentException) { /// handle known or specific exceptions here } else { /// log then rethrow unhandled exceptions here logExceptions(ex); throw; } }