Как предотвратить завершение ASP.net WP при ошибке - PullRequest
2 голосов
/ 24 февраля 2012

У меня есть некоторый код в моем проекте ASP.net MVC, который асинхронно отправляет сообщение. При определенных обстоятельствах этот код может потерпеть неудачу и вызвать незапланированное исключение. У меня нет прямого доступа к коду, который генерирует исключение, или коду, который генерирует поток, поэтому я не могу поймать и обработать ошибку там. Я попытался отловить на уровне Application_Error в Global.asax, но эта функция вызывается только для ошибок страницы, а не для фоновых ошибок. Я также попытался перехватить модуль HTTP, реализовав OnUnhandledException, но не смог найти способ перехватить исключение и предотвратить существование там рабочего процесса.

Есть ли способ предотвратить такие смертельные ошибки? Я понимаю, что это серьезные ошибки, и их следует устранять, но я бы предпочел, чтобы они не прерывали рабочий процесс для других пользователей на других страницах.

Более подробная информация:

Диспетчером сообщений является EventStore, и я считаю, что проблема, с которой я столкнулся в этом случае, заключалась в том, что он попытался десериализовать сообщение, в котором реализован ICommand из предыдущей версии NServiceBus. После обновления до последней беты десериализация не удалась. К сожалению, я тупо удалил коммит, который вызывал ошибку, поэтому я не могу полностью продублировать проблему.

Лучший способ, который я нашел для симуляции ошибки, - это

   public virtual ActionResult Error()
    {
        Task.Factory.StartNew(blowup);
        return new EmptyResult();
    }
    private void blowup()
    {
        throw new Exception("snap");
    }

Вы заметите, что исключение привязки генерируется и обрабатывается правильно, не вызывая проблем. Однако, если вы подождете, то тот факт, что мы не наблюдали свойство исключения для Task, в конечном итоге уничтожит все приложение.

Проверено на Кассини, но подобное поведение наблюдается в IIS 7.5.

Ответы [ 2 ]

1 голос
/ 25 февраля 2012

.NET 1.1 имел backstop для всех необработанных исключений. Он тихо поймает их и продолжит свой веселый путь.

В .NET 2.0 Microsoft изменила это на поведение, которое вы сейчас видите: любое полностью необработанное исключение приведет к остановке процесса, но вы можете обработать некоторые из этих асинхронных исключений с помощью «Handler Soup» метода Application_Error, Thread. Событие UnhandledException и в .NET 4.0 TaskScheduler.UnobservedTaskException.

Microsoft предоставляет значение конфигурации для восстановления поведения .NET 1.1, которое может быть действительно критичным в веб-приложении, где одно ошибочное исключение может перезапустить весь процесс, уничтожая ценные элементы кэша в процессе.

В разделе <runtime>:

<legacyUnhandledExceptionPolicy enabled="1"/>

Статья Microsoft Исключения в управляемых потоках объясняет все это более подробно.

1 голос
/ 24 февраля 2012

Проблема в том, что любое необработанное исключение приводит к прерыванию процесса.Эта проблема не имеет ничего общего с ASP.NET.

Подключите событие unobservedtaskexception (http://msdn.microsoft.com/en-us/library/system.threading.tasks.taskscheduler.unobservedtaskexception.aspx), чтобы перехватить все исключения (и отправить вас и электронную почту).

Я считаючтобы перехватить это событие, плюс событие Application_Error плюс событие Thread.UnhandledException.

...