Windows Service Exception Handling and Timers
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
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.