Question

I've an issue with System.Timers.Timer. Precisely it doesn't throw any Exceptions. Here is my code:

private Timer MyTimer { get; set; }

public MyService()
{
    InitializeComponent();
    AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
    MyTimer = new Timer(10 * 1000);
    MyTimer.Elapsed += MyTimer_Elapsed;
}

protected override void OnStart(string[] args)
{
    MyTimer.Enabled = true;
}

private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    if (!EventLog.SourceExists(EVENTLOGSOURCE))
    {
        EventLog.CreateEventSource(EVENTLOGSOURCE, EVENTLOGDESCRIPTION);
    }
    EventLog.WriteEntry(EVENTLOGSOURCE, "UnhandledException\r\n" + e.ExceptionObject, EventLogEntryType.Error);
    EventLog.WriteEntry(EVENTLOGSOURCE, "UnhandledExceptionEventArgs.IsTerminating: " + e.IsTerminating, EventLogEntryType.Error);

    if (e.IsTerminating)
    {
        this.ExitCode = 100;
        //this.Stop();
    }
}

private void MyTimer_Elapsed(object sender, ElapsedEventArgs e)
{
    MyTimer.Enabled = false;
    CurrentDomain_UnhandledException(AppDomain.CurrentDomain, new UnhandledExceptionEventArgs(new Exception("FakeExceptionForTestPurposeOnly: It will be logged!"), false));

    Int32 i = Convert.ToInt32("10_ForSureGeneratesException_10");
}

So, in my event log i can find "FakeExceptionForTestPurposeOnly: It will be logged!" but it's the only one!

Afterall, the worse part is the service it's still running. How that even possible?

Please note i already solved the problem, in that case the use of timer is not mandatory. System.Threading.Thread does the trick and works as a clockwork. I'm just curious i guess...

So the question is: why during the occurrence of any UnhandledExceptions in MyTimer_Elapsed() "CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)" never will be fired?

Any helps, suggestions, comments will be appreciated

Was it helpful?

Solution

In a Windows Service, the "Main" thread is owned by the Service Control Manager, which is who calls the OnStart and OnStop methods. When an exception occurs on its "Main" thread, the ServiceBase class is in charge of exception handling, thus takes care of the exception and doesn't propagate it up the call chain.

Although there should be no SynchronizationContext inside a Windows Service, hence the Elapsed event should be fired on a different ThreadPool thread, i would suggest you to try System.Threading.Timer instead, and see if the exception propagates when the Elapsed event calls your callback.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top