3

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

Francesco Milani
  • 415
  • 4
  • 11
  • this.Stop(); is commented??!! – Neel Aug 01 '14 at 06:54
  • yes it is :-) but it doesn't matter. The reason for the presence of "this.Stop();" it's merely realted to prevent service autorestart during debug (cause windows handles restart of the service when stops with errors). The issue it's "MyTimer doesn't fire UnhandledException" – Francesco Milani Aug 01 '14 at 07:01
  • Can you add a little more explanation? You say you're curious about *something* but I've no idea what you're curious about. What did you expect to happen and what did/didn't happen that didn't match your expectations? – Damien_The_Unbeliever Aug 01 '14 at 07:14
  • @Damien_The_Unbeliever during my last edit i just added what i'm courious about. – Francesco Milani Aug 01 '14 at 07:29

1 Answers1

3

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.

Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
  • 1
    You're right the problem is the synchronization context. [synchronizingobject](http://msdn.microsoft.com/en-us/library/system.timers.timer.synchronizingobject(v=vs.110).aspx) – Francesco Milani Aug 01 '14 at 09:11