Le eccezioni non gestite causano ASP. Applicazioni basate su NET per uscire in modo imprevisto in .NET Framework

Questo articolo consente di risolvere il problema in cui le eccezioni non gestite causano ASP. Applicazioni basate su NET per uscire in modo imprevisto in .NET Framework.

Versione originale del prodotto: .NET Framework 4.5
Numero KB originale: 911816

Nota

Questo articolo si applica a Microsoft .NET Framework 2.0 e a tutte le versioni successive.

Sintomi

Quando viene generata un'eccezione non gestita in un asp. L'applicazione basata su NET basata su .NET Framework 2.0 e versioni successive viene chiusa in modo imprevisto. Quando si verifica questo problema, nel log dell'applicazione non vengono registrate informazioni sulle eccezioni necessarie per comprendere il problema.

Tuttavia, un messaggio di evento simile all'esempio seguente può essere registrato nel log di sistema. Inoltre, nel log dell'applicazione potrebbe essere registrato un messaggio di evento simile all'esempio seguente.

Causa

Questo problema si verifica perché i criteri predefiniti per le eccezioni non gestite sono stati modificati in .NET Framework 2.0 e versioni successive. Per impostazione predefinita, il criterio per le eccezioni non gestite consiste nel terminare il processo di lavoro.

In .NET Framework 1.1 e in .NET Framework 1.0 le eccezioni non gestite nei thread gestiti sono state ignorate. A meno che non sia stato collegato un debugger per intercettare l'eccezione, non ci si rende conto che si è verificato un problema.

ASP.NET usa i criteri predefiniti per le eccezioni non gestite in .NET Framework 2.0 e versioni successive. Quando viene generata un'eccezione non gestita, l'ASP. L'applicazione basata su NET si chiude in modo imprevisto.

Questo comportamento non si applica alle eccezioni che si verificano nel contesto di una richiesta. Questi tipi di eccezioni vengono comunque gestiti e di cui viene eseguito il wrapping da un HttpException oggetto . Le eccezioni che si verificano nel contesto di una richiesta non causano la fine del processo di lavoro. Tuttavia, le eccezioni non gestite al di fuori del contesto di una richiesta, ad esempio le eccezioni in un thread timer o in una funzione di callback, causano la fine del processo di lavoro.

Risoluzione 1

Modificare il codice sorgente per l'oggetto IHttpModule in modo che registri le informazioni sulle eccezioni nel log dell'applicazione. Le informazioni registrate includono quanto segue:

  • Percorso della directory virtuale in cui si è verificata l'eccezione
  • Nome dell'eccezione
  • Il messaggio
  • Analisi dello stack

Per modificare l'oggetto IHttpModule , seguire questa procedura.

Nota

Questo codice registra un messaggio con il tipo di evento Error e l'origine evento di ASP.NET 2.0.50727.0 nel registro applicazioni. Per testare il modulo, richiedere una pagina ASP.NET che usa il ThreadPool.QueueUserWorkItem metodo per chiamare un metodo che genera un'eccezione non gestita.

  1. Inserire il codice seguente in un file denominato 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. Salvare il file UnhandledExceptionModule.cs nella C:\Program Files\Microsoft Visual Studio 8\VC cartella .

  3. Aprire il prompt dei comandi di Visual Studio.

  4. Digitare sn.exe -k key.snke quindi premere INVIO.

  5. Digitare csc /t:library /r:system.web.dll,system.dll /keyfile:key.snk UnhandledExceptionModule.cse quindi premere INVIO.

  6. Digitare gacutil.exe /if UnhandledExceptionModule.dlle quindi premere INVIO.

  7. Digitare ngen install UnhandledExceptionModule.dlle quindi premere INVIO.

  8. Digitare gacutil /l UnhandledExceptionModulee quindi premere INVIO per visualizzare il nome sicuro per il file UnhandledExceptionModule .

  9. Aggiungere il codice seguente al file Web.config dell'ASP. Applicazione basata su NET.

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

Risoluzione 2

Ripristinare il comportamento predefinito dei criteri di eccezione non gestiti in .NET Framework 1.1 e in .NET Framework 1.0.

Nota

Non è consigliabile modificare il comportamento predefinito. Se si ignorano le eccezioni, l'applicazione potrebbe perdere risorse e abbandonare i blocchi.

Per abilitare questo comportamento predefinito, aggiungere il codice seguente al file Aspnet.config che si trova nella cartella seguente:
%WINDIR%\Microsoft.NET\Framework\v2.0.50727

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

Stato

Si tratta di un comportamento legato alla progettazione del prodotto.

Ulteriori informazioni

Per altre informazioni sulle modifiche in .NET Framework 2.0, vedere Modifiche di rilievo in .NET Framework 2.0.