If you really need to manually spawn managed threads, I think the AppDomain.UnhandledException event is your only choice for non-fatal exceptions since Application_Error
does not get called for exceptions thrown outside the request processing context.
Depending on what you're doing in your background threads, you may want to switch to the async/await model for I/O-bound operations or TPL in general for CPU-bound tasks.