Las excepciones no controladas provocan ASP. Aplicaciones basadas en NET para salir inesperadamente en .NET Framework

Este artículo le ayuda a resolver el problema en el que las excepciones no controladas provocan ASP. Aplicaciones basadas en NET para salir inesperadamente en .NET Framework.

Versión original del producto: .NET Framework 4.5
Número de KB original: 911816

Nota:

Este artículo se aplica a Microsoft .NET Framework 2.0 y a todas las versiones posteriores.

Síntomas

Cuando se produce una excepción no controlada en una ASP. La aplicación basada en NET que se basa en .NET Framework 2.0 y versiones posteriores, se cierra inesperadamente. Cuando se produce este problema, no hay ninguna información de excepción que tenga que tener para comprender que el problema se registra en el registro de la aplicación.

Sin embargo, se puede registrar un mensaje de evento similar al ejemplo siguiente en el registro del sistema. Además, se puede registrar un mensaje de evento similar al ejemplo siguiente en el registro de la aplicación.

Causa

Este problema se produce porque la directiva predeterminada para excepciones no controladas ha cambiado en .NET Framework 2.0 y versiones posteriores. De forma predeterminada, la directiva de excepciones no controladas es finalizar el proceso de trabajo.

En .NET Framework 1.1 y en .NET Framework 1.0, se omitieron las excepciones no controladas en subprocesos administrados. A menos que adjunte un depurador para detectar la excepción, no se dará cuenta de que algo estaba mal.

ASP.NET usa la directiva predeterminada para las excepciones no controladas en .NET Framework 2.0 y versiones posteriores. Cuando se produce una excepción no controlada, el ASP. La aplicación basada en NET se cierra inesperadamente.

Este comportamiento no se aplica a las excepciones que se producen en el contexto de una solicitud. Estos tipos de excepciones todavía se controlan y encapsulan mediante un HttpException objeto . Las excepciones que se producen en el contexto de una solicitud no hacen que finalice el proceso de trabajo. Sin embargo, las excepciones no controladas fuera del contexto de una solicitud, como las excepciones en un subproceso del temporizador o en una función de devolución de llamada, hacen que el proceso de trabajo finalice.

Solución 1

Modifique el código fuente del IHttpModule objeto para que registre información de excepción en el registro de la aplicación. La información que se registra incluirá lo siguiente:

  • Ruta de acceso del directorio virtual en la que se produjo la excepción
  • Nombre de la excepción
  • El mensaje
  • Seguimiento de la pila

Para modificar el IHttpModule objeto, siga estos pasos.

Nota:

Este código registrará un mensaje que tiene el tipo de error de evento y el origen de eventos de ASP.NET 2.0.50727.0 en el registro de la aplicación. Para probar el módulo, solicite una página de ASP.NET que use el ThreadPool.QueueUserWorkItem método para llamar a un método que produce una excepción no controlada.

  1. Coloque el código siguiente en un archivo denominado 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. Guarde el archivo UnhandledExceptionModule.cs en la C:\Program Files\Microsoft Visual Studio 8\VC carpeta .

  3. Abra el símbolo del sistema de Visual Studio.

  4. Escriba sn.exe -k key.snky, a continuación, presione ENTRAR.

  5. Escriba csc /t:library /r:system.web.dll,system.dll /keyfile:key.snk UnhandledExceptionModule.csy, a continuación, presione ENTRAR.

  6. Escriba gacutil.exe /if UnhandledExceptionModule.dlly, a continuación, presione ENTRAR.

  7. Escriba ngen install UnhandledExceptionModule.dlly, a continuación, presione ENTRAR.

  8. Escriba gacutil /l UnhandledExceptionModuley presione ENTRAR para mostrar el nombre seguro del archivo UnhandledExceptionModule .

  9. Agregue el código siguiente al archivo Web.config de asp. Aplicación basada en NET.

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

Solución 2

Vuelva a cambiar la directiva de excepciones no controlada al comportamiento predeterminado que se produce en .NET Framework 1.1 y en .NET Framework 1.0.

Nota:

No se recomienda cambiar el comportamiento predeterminado. Si omite las excepciones, es posible que la aplicación pierda recursos y abandone los bloqueos.

Para habilitar este comportamiento predeterminado, agregue el código siguiente al archivo Aspnet.config que se encuentra en la carpeta siguiente:
%WINDIR%\Microsoft.NET\Framework\v2.0.50727

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

Estado

Este comportamiento es una característica del diseño de la aplicación.

Más información

Para obtener más información sobre los cambios en .NET Framework 2.0, visite Cambios importantes en .NET Framework 2.0.