C# ASP.net应用程序\u计时器中的启动捕获异常

C# ASP.net应用程序\u计时器中的启动捕获异常,c#,asp.net,exception,timer,exception-handling,C#,Asp.net,Exception,Timer,Exception Handling,给定Global.asax中的以下代码,将正确捕获引发的第一个异常,但不会捕获计时器异常 要捕获计时器中的任何异常,我需要更改什么 protected void Application_Start(object sender, EventArgs e) { // THIS WORKS try { throw new Exception("Test!"); } catch (Exception ex) { Code.H

给定
Global.asax
中的以下代码,将正确捕获引发的第一个异常,但不会捕获计时器异常

要捕获计时器中的任何异常,我需要更改什么

protected void Application_Start(object sender, EventArgs e)
{
    // THIS WORKS
    try
    {
        throw new Exception("Test!");
    }
    catch (Exception ex)
    {
        Code.Helpers.Error.Functions.RecordError(ex);
    }

    // THIS DOESN'T WORK
    try
    {
        var myTimer = new Timer(
            Code.Helpers.MyTimer.Process,
            null,
            new TimeSpan(0, 0, 0, 0),
            Settings.ProcessMyTimerEvery);
    }
    catch (Exception ex)
    {
        Code.Helpers.Error.Functions.RecordError(ex);
    }
}

您应该将
try
/
catch
块放在计时器回调中(
code.Helpers.MyTimer.Process
)。

来自文档(我的重点):

提供一种机制,用于以指定的间隔在线程池线程上执行方法

也值得一读:

为回调指定的方法应该是可重入的,因为它是在线程池线程上调用的。如果计时器间隔小于执行该方法所需的时间,或者如果所有线程池线程都在使用且该方法已排队多次,则可以在两个线程池线程上同时执行该方法

这意味着传入计时器的委托不会在计时器所在的同一线程上调用。要捕获计时器事件中的异常,需要将try/catch放在其中。例如:

var myTimer = new Timer(
    TimerEvent, //<-- A delegate to the TimerEvent method
    null, 
    new TimeSpan(0, 0, 0, 0), 
    new TimeSpan(0, 0, 0, 5));

您希望在第二次
尝试中出现哪种异常?您只创建
Timer
实例。您需要将
try/catch
放入计时器事件处理程序中。
private void TimerEvent(object x)
{
    try
    {
        throw new Exception("Exception in timer event");
    }
    catch (Exception ex)
    {
        Code.Helpers.Error.Functions.RecordError(ex);
    }
}