Exceções sem tratamento fazem com que o ASP. NET para encerrar inesperadamente no .NET Framework
Este artigo ajuda a resolver o problema em que exceções sem tratamento fazem com que o ASP. NET sejam encerrados inesperadamente no .NET Framework.
Versão original do produto: .NET Framework 4.5
Número original do KB: 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 sem tratamento é lançada em um aplicativo ASP. NET criado no .NET Framework 2.0 e versões posteriores, o aplicativo é encerrado 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.
Causa
Esse problema ocorre porque a política padrão para exceções sem tratamento foi alterada no .NET Framework 2.0 e versões posteriores. Por padrão, a política para exceções sem tratamento é encerrar o processo de trabalho.
No .NET Framework 1.1 e no .NET Framework 1.0, exceções sem tratamento em threads gerenciados foram ignoradas. A menos que você anexasse um depurador para capturar a exceção, você não perceberia que algo estava errado.
ASP.NET usa a política padrão para exceções sem tratamento no .NET Framework 2.0 e versões posteriores. Quando uma exceção sem tratamento é lançada, o aplicativo ASP. NET é encerrado 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 tratados e encapsulados por um HttpException
objeto. As 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 sem tratamento 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 seja encerrado.
Resoluçã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 a exceção ocorreu
- 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 que tem o Tipo de Evento de Erro e a Origem do Evento de ASP.NET 2.0.50727.0 no log do aplicativo. Para testar o módulo, solicite uma página de ASP.NET que use o ThreadPool.QueueUserWorkItem
método para chamar um método que gere uma exceção sem tratamento.
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); } } }
Salve o arquivo UnhandledExceptionModule.cs na
C:\Program Files\Microsoft Visual Studio 8\VC
pasta.Abra o prompt de comando do Visual Studio.
Digite
sn.exe -k key.snk
e pressione ENTER.Digite
csc /t:library /r:system.web.dll,system.dll /keyfile:key.snk UnhandledExceptionModule.cs
e pressione ENTER.Digite
gacutil.exe /if UnhandledExceptionModule.dll
e pressione ENTER.Digite
ngen install UnhandledExceptionModule.dll
e pressione ENTER.Digite
gacutil /l UnhandledExceptionModule
e pressione ENTER para exibir o nome forte do arquivo UnhandledExceptionModule .Adicione o código a seguir ao arquivo Web.config do seu aplicativo ASP. NET.
<add name="UnhandledExceptionModule" type="WebMonitor.UnhandledExceptionModule, <strong name>" />
Resolução 2
Altere a política de exceção sem tratamento 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 comportamento ocorre por design.
Mais informações
Para obter mais informações sobre alterações no .NET Framework 2.0, visite Alterações recentes no .NET Framework 2.0.