8

How is an ASP.NET application supposed to deal with unhandled exceptions which are occuring on a non-request background thread (due to bugs)?

By default, such exceptions cause the process to terminate. This is unacceptable in the setting of an ASP.NET worker process because concurrently running requests are aborted unpredictably. It is also a performance problem.

Exceptions on a request thread are not a problem because ASP.NET handles them (by showing an error page).

The AppDomain.UnhandledException event allows to observe that an exception has occurred, but termination cannot be prevented at that point.

Here is a repro which needs to be pasted into an ASPX page codebehind.

protected void Page_Load(object sender, EventArgs e)
{
    var thread = new Thread(() =>
        {
            throw new InvalidOperationException("some failure on a helper thread");
        });
    thread.Start();
    thread.Join();
}

The only solution I know of is to never let an exception "escape" unhandled. Is there any other, more global and thorough solution for this?

usr
  • 168,620
  • 35
  • 240
  • 369
  • I'm experiencing same problem ... its strange how asp.net team never considered a solution to this. I have a third part http module that is failing at some point and throwing exceptions which cause the worker process to display "Service Unavailable" !!! – Jalal El-Shaer Jun 28 '12 at 07:21

3 Answers3

1

Rx (Reactive Programming) was born to solve issues like this, try to consider changing the framework you currently use and replace it with Rx

http://msdn.microsoft.com/en-us/data/gg577609.aspx

The Nugget packages:

https://nuget.org/packages/Rx-Main/1.0.11226

This is the equivalent Rx code:

        var o = Observable.Start(() => { throw new NotImplementedException(); });

        o.Subscribe(
            onNext => { },
            onError => { },
            () => { Console.WriteLine("Operation done"); });

As you can see the error won't escape the background thread when you specify a handler for the error, onError => { }

If you do not specify an error handler, the exception will be propagated:

        o.Subscribe(
            onNext => { },
            () => { Console.WriteLine("Operation done"); });

In the example above, the exception will be propagated and will cause the same problems as your posted code

Jupaol
  • 21,107
  • 8
  • 68
  • 100
  • I'm doing threading in a context where I'm not dealing with streams of events. Not sure if Rx is a good fit here. – usr Jun 20 '12 at 10:20
  • Well, Rx is much more than just dealing with stream of events, that was the main objective but the framework has evolved and know it contains a rich API to deal with async methods. The only reason I would not recommend Rx **yet**, is if you run your backgrounds threads in parallel, even when Rx provides an API for this, I have found that it's better to use the `Task` object – Jupaol Jun 20 '12 at 10:26
0

You can mark the exception as handled in an unhandled exception handler. https://msdn.microsoft.com/en-us/library/system.windows.applicationunhandledexceptioneventargs.handled(v=vs.95)

That should prevent the worker process from recycling because of an error on the background thread.

You wouldn't do that for all exceptions though. Just the ones you know are safe to ignore.

Wonko
  • 331
  • 1
  • 5
0

I think "legacyUnhandledExceptionPolicy" option is your answer.

Unhandled exceptions causing ASP.NET to crash in .NET 2.0 ; http://blogs.msdn.com/b/tom/archive/2007/12/04/unhandled-exceptions-causing-asp-net-to-crash-in-net-2-0.aspx

SeongTae Jeong
  • 325
  • 2
  • 8
  • Thanks, but I especially want to avoid crashes and I don't think turning on legacy settings is a future proof way forward. – usr Oct 09 '15 at 17:57