Dela via


Ohanterade undantag orsakar ASP. NET-baserade program avslutas oväntat i .NET Framework

Den här artikeln hjälper dig att lösa problemet där ohanterade undantag orsakar ASP. NET-baserade program avslutas oväntat i .NET Framework.

Ursprunglig produktversion: .NET Framework 4.5
Ursprungligt KB-nummer: 911816

Obs!

Den här artikeln gäller för Microsoft .NET Framework 2.0 och alla senare versioner.

Symptom

När ett ohanterat undantag genereras i en ASP. NET-baserat program som bygger på .NET Framework 2.0 och senare versioner avslutas programmet oväntat. När det här problemet uppstår loggas ingen undantagsinformation som du måste förstå problemet i programloggen.

Ett händelsemeddelande som liknar följande exempel kan dock loggas i systemloggen. Dessutom kan ett händelsemeddelande som liknar följande exempel loggas i programloggen.

Orsak

Det här problemet beror på att standardprincipen för ohanterade undantag har ändrats i .NET Framework 2.0 och senare versioner. Som standard är principen för ohanterade undantag att avsluta arbetsprocessen.

I .NET Framework 1.1 och i .NET Framework 1.0 ignorerades ohanterade undantag på hanterade trådar. Om du inte kopplade ett felsökningsprogram för att fånga undantaget skulle du inte inse att något var fel.

ASP.NET använder standardprincipen för ohanterade undantag i .NET Framework 2.0 och senare versioner. När ett ohanterat undantag utlöses, ASP. NET-baserat program avslutas oväntat.

Det här beteendet gäller inte för undantag som inträffar i kontexten för en begäran. Den här typen av undantag hanteras fortfarande och omsluts av ett HttpException objekt. Undantag som inträffar i kontexten för en begäran leder inte till att arbetsprocessen avslutas. Ohanterade undantag utanför kontexten för en begäran, till exempel undantag i en timertråd eller i en återanropsfunktion, gör dock att arbetsprocessen avslutas.

Lösning 1

Ändra källkoden IHttpModule för objektet så att det loggar undantagsinformation till programloggen. Informationen som loggas omfattar följande:

  • Den virtuella katalogsökväg där undantaget inträffade
  • Undantagsnamnet
  • Meddelandet
  • Stackspårningen

Följ dessa steg om du vill ändra objektet IHttpModule .

Obs!

Den här koden loggar ett meddelande med händelsetypen Fel och händelsekällan för ASP.NET 2.0.50727.0 i programloggen. Om du vill testa modulen begär du en ASP.NET sida som använder ThreadPool.QueueUserWorkItem metoden för att anropa en metod som utlöser ett ohanterat undantag.

  1. Placera följande kod i en fil med namnet 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. Spara UnhandledExceptionModule.cs-filen i C:\Program Files\Microsoft Visual Studio 8\VC mappen .

  3. Öppna Visual Studio-kommandotolken.

  4. Skriv sn.exe -k key.snkoch tryck sedan på RETUR.

  5. Skriv csc /t:library /r:system.web.dll,system.dll /keyfile:key.snk UnhandledExceptionModule.csoch tryck sedan på RETUR.

  6. Skriv gacutil.exe /if UnhandledExceptionModule.dlloch tryck sedan på RETUR.

  7. Skriv ngen install UnhandledExceptionModule.dlloch tryck sedan på RETUR.

  8. Skriv gacutil /l UnhandledExceptionModuleoch tryck sedan på RETUR för att visa det starka namnet för filen UnhandledExceptionModule .

  9. Lägg till följande kod i Web.config filen för din ASP. NET-baserat program.

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

Lösning 2

Ändra tillbaka den ohanterade undantagsprincipen till standardbeteendet i .NET Framework 1.1 och i .NET Framework 1.0.

Obs!

Vi rekommenderar inte att du ändrar standardbeteendet. Om du ignorerar undantag kan programmet läcka resurser och överge lås.

Om du vill aktivera det här standardbeteendet lägger du till följande kod i denAspnet.config fil som finns i följande mapp:
%WINDIR%\Microsoft.NET\Framework\v2.0.50727

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

Status

Detta är avsiktligt.

Mer information

Mer information om ändringar i .NET Framework 2.0 finns i Icke-bakåtkompatibla ändringar i .NET Framework 2.0.