Whilst implementing a .NET application for one of my clients, I recently ran into a problem where a long running task would just suddenly stop working after about 30 minutes. No error, no exception - nothing. I had been troubleshooting this for 3 days now, and that is a very long time for someone with my experience (if I may say so myself). The difficulty with this problem is that there are no - and I mean absolutely NO errors. The only thing I could gather is that the long running task stops because the IIS worker process dies. I even added detailed trace statements - none of which helped. The output stopped dead at one my of audit entries:
Workflow.Audit.AddAuditEntry(new XXXAudit.XXXAuditEntry(this,
"Some message"));
A couple of minutes ago I decided to put trace statements in the getters I am using here:
protected IWorkflow Workflow
{
get
{
return workflow;
}
}
public IAudit Audit
{
get
{
return Audit;
}
}
Now if you have a sharp eye you might have spotted the bug already. It is trivial, though extremely hard to spot in a 40 000 line application. Only when I saw a runaway amount of debug output entries in the getter for the IAudit interface did I immediately realise what was happening. A stupid thing like a recursive call caused me 3 lost days on a project - that is unacceptable. I guess it is all my fault - I could have used different naming conventions, could have spotted the little recursive icon next to that line in my IDE - but none of that is relevant. Coding conventions certainly help with this problem - and in my own projects I do use a different naming scheme, but in this case I had to follow the client's naming scheme which is based on Microsoft's recommendations. The root problem is that Microsoft should have implemented a check in their compiler to catch this extremely easy to make mistake in your code, and at least let it fail with an error in the trivil case where recursion is infinite. The problem is that getters' syntax makes this kind of mistake extremely easy to make. Another root problem here is the fact that Windows choose to kill the IIS worker process silently and not do like Java does on an infinitely recursive call - abort the call with a StackOverflowException. That would have helped too. Instead there are no exceptions, no (helpful) EventLog entries and just silent death of a process...