Les exceptions non gérées provoquent ASP. Applications basées sur NET à quitter de manière inattendue dans le .NET Framework

Cet article vous aide à résoudre le problème où les exceptions non gérées provoquent ASP. Les applications basées sur NET doivent être interrompues de manière inattendue dans le .NET Framework.

Version du produit d’origine : .NET Framework 4.5
Numéro de la base de connaissances d’origine : 911816

Remarque

Cet article s’applique à Microsoft .NET Framework 2.0 et à toutes les versions ultérieures.

Symptômes

Lorsqu’une exception non gérée est levée dans un ASP. Application basée sur NET basée sur le .NET Framework 2.0 et versions ultérieures, l’application se ferme de façon inattendue. Lorsque ce problème se produit, aucune information d’exception que vous devez avoir pour comprendre le problème n’est consignée dans le journal des applications.

Toutefois, un message d’événement similaire à l’exemple suivant peut être enregistré dans le journal système. En outre, un message d’événement similaire à l’exemple suivant peut être enregistré dans le journal des applications.

Cause

Ce problème se produit car la stratégie par défaut pour les exceptions non gérées a changé dans .NET Framework 2.0 et versions ultérieures. Par défaut, la stratégie pour les exceptions non gérées consiste à mettre fin au processus de travail.

Dans .NET Framework 1.1 et dans le .NET Framework 1.0, les exceptions non gérées sur les threads managés ont été ignorées. À moins que vous n’attachez un débogueur pour intercepter l’exception, vous ne vous rendrez pas compte que quelque chose ne va pas.

ASP.NET utilise la stratégie par défaut pour les exceptions non gérées dans .NET Framework 2.0 et versions ultérieures. Lorsqu’une exception non gérée est levée, asp. L’application basée sur NET se ferme de façon inattendue.

Ce comportement ne s’applique pas aux exceptions qui se produisent dans le contexte d’une requête. Ces types d’exceptions sont toujours gérés et encapsulés par un HttpException objet . Les exceptions qui se produisent dans le contexte d’une requête n’entraînent pas la fin du processus de travail. Toutefois, les exceptions non gérées en dehors du contexte d’une requête, telles que les exceptions sur un thread de minuteur ou dans une fonction de rappel, entraînent la fin du processus de travail.

Résolution 1

Modifiez le code source de l’objet IHttpModule afin qu’il enregistre les informations d’exception dans le journal des applications. Les informations consignées sont les suivantes :

  • Chemin d’accès du répertoire virtuel dans lequel l’exception s’est produite
  • Nom de l’exception
  • Le message
  • Trace de la pile

Pour modifier l’objet IHttpModule , procédez comme suit.

Remarque

Ce code journalisera un message dont le type d’événement est Erreur et la source de l’événement de ASP.NET 2.0.50727.0 dans le journal de l’application. Pour tester le module, demandez une page ASP.NET qui utilise la ThreadPool.QueueUserWorkItem méthode pour appeler une méthode qui lève une exception non gérée.

  1. Placez le code suivant dans un fichier nommé 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. Enregistrez le fichier UnhandledExceptionModule.cs dans le C:\Program Files\Microsoft Visual Studio 8\VC dossier .

  3. Ouvrez l’invite de commandes Visual Studio.

  4. Tapez sn.exe -k key.snk, puis appuyez sur Entrée.

  5. Tapez csc /t:library /r:system.web.dll,system.dll /keyfile:key.snk UnhandledExceptionModule.cs, puis appuyez sur Entrée.

  6. Tapez gacutil.exe /if UnhandledExceptionModule.dll, puis appuyez sur Entrée.

  7. Tapez ngen install UnhandledExceptionModule.dll, puis appuyez sur Entrée.

  8. Tapez gacutil /l UnhandledExceptionModule, puis appuyez sur ENTRÉE pour afficher le nom fort du fichier UnhandledExceptionModule .

  9. Ajoutez le code suivant au fichier Web.config de votre ASP. Application basée sur NET.

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

Résolution 2

Remplacez la stratégie d’exception non gérée par le comportement par défaut qui se produit dans .NET Framework 1.1 et dans .NET Framework 1.0.

Remarque

Nous vous déconseillons de modifier le comportement par défaut. Si vous ignorez les exceptions, l’application peut fuiter des ressources et abandonner des verrous.

Pour activer ce comportement par défaut, ajoutez le code suivant au fichier Aspnet.config qui se trouve dans le dossier suivant :
%WINDIR%\Microsoft.NET\Framework\v2.0.50727

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

Statut

Ce comportement est inhérent au produit.

Plus d’informations

Pour plus d’informations sur les modifications apportées au .NET Framework 2.0, consultez Changements cassants dans .NET Framework 2.0.