HTTPUnhandledException: Request Timed Out.
Every now and then, when a request had a lot of work to do, I would get this exception. It didn't 'ripple up' from a method in the regular way that an exception does. It just caused execution to cease and was caught by the default error handler. There are a few places where timeouts are set. One is in IIS. In the Web Site properties there is a setting called 'connection timeout'. I thought this might be the candidate. So I increased the timeout, but no luck. The operation causing the timeout was an data integration over a network. The integration API had a connection timeout setting too. Changing this timeout had no effect.
Another strange behavior was that in debug mode the problem went away. The operation would complete without the time out. Sadly, I had to debug the problem in release mode, with many symbol files missing. At around the same amount of time I would get an 'ObjectDisposedException' on my NetworkStream object, followed by a ThreadAborted exception.
I found some threads online about the .Net garbage collector prematurely destroying objects if it thought they were out of scope (or might as well be since there were no subsequent references to them). So I daftly started adding Garbage Collector control statements to my code to preserve my objects. Of course this just 'felt' wrong, but hey, desparate times... Well of course no luck.
It always helps to be fresh, and to bring in a fresh perspective. So, with the help of a coworker we clarified 2 important clues.
- Something is terminating the worker thread
- The thread is terminated after 90 seconds
There was definitely a timeout somewhere which was bringing everything to a halt. I already knew it wasn't the IIS connection timeout, but what about this ASP Script timeout under virtual directory configuration? It was set to 90 seconds too! Alas, it was not the culprit. Which of course made sense after I tested it, but ya never know.
The Almighty Interweb
How did I code before the Internet? (Yes I am that old). Some Googling later I discovered, da na na naah! An obscure, yet highly important setting in machine.config. Something that ASP.Net uses to terminate threads. Something that is defaulted to 90 seconds. The answer, the culprit! A glorious little piece of XML.
Allow me to introduce executionTimeout. It looks like this,
It is set to 90 seconds in machine.config, and does not appear in the default web.config file that VS.NET creates for Web Applications. Every ASP.NET developer should be aware of this setting. Why is it kept hidden away? Ahhh, the eternal mysteries... Anyhow, there it is. Add it to your web.config. Pass it on.