In a comment you mentioned:
This is a web-site rather than web app.
"Web site" vs. "web app" seems like a moot distinction at this point. There's enough complexity in the code that it's an "application" by pretty much any definition of the word. To that point, if the application host doesn't meaningfully manage thread faults for you (and I wouldn't expect a web application host to do so) then you have to manage them manually.
In this case I see that as one of two options:
Option 1: Don't let your threads end in a faulted state. Whatever your top-level worker item for any given thread is (a method invoked at the start of the thread, a loop repeating operations, etc.), that needs to be essentially fault-proof. No exception should get past that. Which means it needs to be dead simple (so as to not throw exceptions of its own) and needs to catch any and all exceptions from the operation(s) it invokes.
Once caught, do with them as you please. Roll back a unit of work, notify someone of the error, etc.
Option 2: Move the long-running thread operations out of the web application, since web applications aren't really suited for ongoing background processes. A Windows Service or scheduled Console Application is a much more suited application host for that logic.
Yes, bit of a re-write there though.
Is it? It shouldn't be. That's really a matter of how the code was originally architected, not related to the application hosts themselves. Invoking a business operation from one application host is the same as invoking it from another. If the logic is tightly coupled to the application technology, that's a separate problem. And there's no quick fix to that problem. The good news is that once you fix that problem, other problems (like the one which prompted this question) are quick fixes.