Exceções não tratadas causam ASP. Aplicativos baseados em NET para sair inesperadamente no .NET Framework

Este artigo ajuda você a resolve o problema em que exceções não tratadas causam ASP. Aplicativos baseados em NET para parar inesperadamente no .NET Framework.

Versão original do produto: .NET Framework 4.5
Número de KB original: 911816

Observação

Este artigo se aplica ao Microsoft .NET Framework 2.0 e a todas as versões posteriores.

Sintomas

Quando uma exceção não tratada é gerada em um ASP. Aplicativo baseado em NET criado nas versões 2.0 e posteriores .NET Framework, o aplicativo desativa inesperadamente. Quando esse problema ocorre, nenhuma informação de exceção que você deve ter para entender o problema é registrada no log do aplicativo.

No entanto, uma mensagem de evento semelhante ao exemplo a seguir pode ser registrada no log do Sistema. Além disso, uma mensagem de evento semelhante ao exemplo a seguir pode ser registrada no log do aplicativo.

Motivo

Esse problema ocorre porque a política padrão para exceções não tratadas foi alterada nas versões .NET Framework 2.0 e posteriores. Por padrão, a política para exceções não tratadas é encerrar o processo de trabalho.

No .NET Framework 1.1 e no .NET Framework 1.0, exceções não tratadas em threads gerenciados foram ignoradas. A menos que você anexou um depurador para pegar a exceção, você não perceberia que algo estava errado.

ASP.NET usa a política padrão para exceções não tratadas nas versões .NET Framework 2.0 e posteriores. Quando uma exceção não tratada é gerada, o ASP. O aplicativo baseado em NET desiste inesperadamente.

Esse comportamento não se aplica a exceções que ocorrem no contexto de uma solicitação. Esses tipos de exceções ainda são manipulados e encapsulados por um HttpException objeto. Exceções que ocorrem no contexto de uma solicitação não fazem com que o processo de trabalho seja encerrado. No entanto, exceções não tratadas fora do contexto de uma solicitação, como exceções em um thread de temporizador ou em uma função de retorno de chamada, fazem com que o processo de trabalho termine.

Solução 1

Modifique o código-fonte do IHttpModule objeto para que ele registre informações de exceção no log do aplicativo. As informações registradas incluirão o seguinte:

  • O caminho do diretório virtual no qual ocorreu a exceção
  • O nome da exceção
  • A mensagem
  • O rastreamento de pilha

Para modificar o IHttpModule objeto, siga estas etapas.

Observação

Esse código registrará uma mensagem com o Tipo de Erro de Evento e a Fonte de Evento do ASP.NET 2.0.50727.0 no log do aplicativo. Para testar o módulo, solicite um ASP.NET página que usa o ThreadPool.QueueUserWorkItem método para chamar um método que gera uma exceção sem tratamento.

  1. Coloque o código a seguir em um arquivo chamado UnhandledExceptionModule.cs.

    using System;
    using System.Diagnostics;
    using System.Globalization;
    using System.IO;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Threading;
    using System.Web;
    
    namespace WebMonitor
    {
        public class UnhandledExceptionModule: IHttpModule
        {
    
            static int _unhandledExceptionCount = 0;
            static string _sourceName = null;
            static object _initLock = new object();
            static bool _initialized = false;
    
            public void Init(HttpApplication app)
            {
    
                // Do this one time for each AppDomain.
                if (!_initialized)
                {
                    lock (_initLock)
                    {
                        if (!_initialized)
                        {
                            string webenginePath = Path.Combine(RuntimeEnvironment.GetRuntimeDirectory(),
                            "webengine.dll");
    
                            if (!File.Exists(webenginePath))
                            {
                                throw new Exception(String.Format(CultureInfo.InvariantCulture,
                                                            "Failed to locate webengine.dll at '{0}'.
                                                            This module requires .NET Framework 2.0.",
                                                                  webenginePath));
                            }
    
                            FileVersionInfo ver = FileVersionInfo.GetVersionInfo(webenginePath);
                            _sourceName = string.Format(CultureInfo.InvariantCulture,
                             "ASP.NET {0}.{1}.{2}.0",
                                                        ver.FileMajorPart, ver.FileMinorPart,
                                                         ver.FileBuildPart);
    
                            if (!EventLog.SourceExists(_sourceName))
                            {
                                throw new Exception(String.Format(CultureInfo.InvariantCulture,
                                                            "There is no EventLog source named '{0}'.
                                                            This module requires .NET Framework 2.0.",
                                                                  _sourceName));
                            }
    
                            AppDomain.CurrentDomain.UnhandledException +=
                            new UnhandledExceptionEventHandler(OnUnhandledException);
    
                            _initialized = true;
                        }
                    }
                }
            }
    
            public void Dispose()
            {
            }
    
            void OnUnhandledException(object o, UnhandledExceptionEventArgs e)
            {
                // Let this occur one time for each AppDomain.
                if (Interlocked.Exchange(ref _unhandledExceptionCount, 1) != 0)
                    return;
    
                StringBuilder message = new StringBuilder("\r\n\r\nUnhandledException logged by
                UnhandledExceptionModule.dll:\r\n\r\nappId=");
    
                string appId = (string) AppDomain.CurrentDomain.GetData(".appId");
                if (appId != null)
                {
                    message.Append(appId);
                }
    
                Exception currentException = null;
                for (currentException = (Exception)e.ExceptionObject; currentException != null;
                currentException = currentException.InnerException)
                {
                    message.AppendFormat("\r\n\r\ntype={0}\r\n\r\nmessage={1}
                    \r\n\r\nstack=\r\n{2}\r\n\r\n",
                                         currentException.GetType().FullName,
                                         currentException.Message,
                                         currentException.StackTrace);
                }
    
                EventLog Log = new EventLog();
                Log.Source = _sourceName;
                Log.WriteEntry(message.ToString(), EventLogEntryType.Error);
            }
        }
    }
    
  2. Salve o arquivo UnhandledExceptionModule.cs na C:\Program Files\Microsoft Visual Studio 8\VC pasta.

  3. Abra o Prompt de Comando do Visual Studio.

  4. Digite sn.exe -k key.snke pressione ENTER.

  5. Digite csc /t:library /r:system.web.dll,system.dll /keyfile:key.snk UnhandledExceptionModule.cse pressione ENTER.

  6. Digite gacutil.exe /if UnhandledExceptionModule.dlle pressione ENTER.

  7. Digite ngen install UnhandledExceptionModule.dlle pressione ENTER.

  8. Digite gacutil /l UnhandledExceptionModulee pressione ENTER para exibir o nome forte do arquivo UnhandledExceptionModule .

  9. Adicione o código a seguir ao arquivoWeb.config de seu ASP. Aplicativo baseado em NET.

    <add name="UnhandledExceptionModule"
    type="WebMonitor.UnhandledExceptionModule, <strong name>" />
    

Solução 2

Altere a política de exceção não tratada de volta para o comportamento padrão que ocorre no .NET Framework 1.1 e no .NET Framework 1.0.

Observação

Não recomendamos que você altere o comportamento padrão. Se você ignorar exceções, o aplicativo poderá vazar recursos e abandonar bloqueios.

Para habilitar esse comportamento padrão, adicione o seguinte código ao arquivo Aspnet.config localizado na seguinte pasta:
%WINDIR%\Microsoft.NET\Framework\v2.0.50727

<configuration>
     <runtime>
         <legacyUnhandledExceptionPolicy enabled="true" />
     </runtime>
</configuration>

Status

Este é o comportamento padrão.

Mais informações

Para obter mais informações sobre alterações no .NET Framework 2.0, visite Breaking Changes in .NET Framework 2.0.