是否可以在 C# 类中为多个计时器设置一个异常处理程序? [英] Is it possible to have one Exception handler for multiple timers in a C# class?

查看:23
本文介绍了是否可以在 C# 类中为多个计时器设置一个异常处理程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a C# program which runs a system tray application - transferring / moving / creating / editing files in the background.

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

There is alot of exception handling and loop handling to prevent the program from crashing / getting stuck if the user manual deletes a file the program is working with.

不幸的是,运行程序的其中一台计算机出现程序崩溃.电脑很难拿到,不能装调试软件(是嵌入式的外置电脑,不能上网).

Unfortunately one of the computer the program is running on is having the program crash. The computer is very hard to get, and cannot have debugging software loaded on (it is an embedded PC outside with no network access).

我已尝试查找崩溃的原因(例如未处理的异常),但没有找到任何内容,并且无法访问位于远程位置的 PC.

I have tried finding the cause of the crash (such as an unhandled exeption) however have not found anything and do not have access to the PC as it is in a remote location.

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

I was hoping to find a way to use AppDomain / an UnhandledExceptionEventHandler to catch all unhandled exceptions and log them for diagnosis. However the exception I have (deliberately) created in the office inside the class "DoSomething.class", are crashing the WinForm application rather than logging the exception error.

我的代码是:

    //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");
    }

为什么 throw new 异常不调用未处理的异常错误?我将如何使用 AppDomain 获取未处理的异常处理程序来处理 RunChangeFiles 中的此异常/异常?

AppDomain 上的代码基于 MSDN 示例

Code on AppDomain is based of MSDN examples

推荐答案

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

If your timer is a System.Timers.Timer the reason is documented by MSDN here:

Timer 组件捕获并抑制 Elapsed 事件的事件处理程序抛出的所有异常.

The Timer component catches and suppresses all exceptions thrown by event handlers for the Elapsed event.

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

您必须捕获在经过处理的处理程序中抛出的异常,并在 ThreadPool 线程上重新抛出它们.

You'll have to catch the exceptions that are thrown in the elapsed handler, and rethrow them on a ThreadPool thread.

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

Using your code above and extending the answer from the referenced question:

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 事件来处理未处理的异常.


If your timer is a System.Windows.Forms.Timer then you will need to hook into the Application.ThreadException event to handle unhandled exceptions.

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

Subscribe to this event prior to calling Application.Run().

您还可以在重新抛出异常之前在本地异常处理块中处理 Exception 的日志记录.

You can also handle logging of the Exception in a local exception handling block before rethrowing the 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;  
    }
}

这篇关于是否可以在 C# 类中为多个计时器设置一个异常处理程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆