Nieobsługiwane wyjątki powodują asp. Aplikacje oparte na platformie NET nieoczekiwanie zamykają się w programie .NET Framework
Ten artykuł pomaga rozwiązać problem polegający na tym, że nieobsługiwane wyjątki powodują asp. Aplikacje oparte na platformie NET nieoczekiwanie zamykają się w programie .NET Framework.
Oryginalna wersja produktu: .NET Framework 4.5
Oryginalny numer KB: 911816
Uwaga 16.
Ten artykuł dotyczy programu Microsoft .NET Framework 2.0 i wszystkich nowszych wersji.
Symptomy
W przypadku zgłoszenia nieobsługiwanego wyjątku na platformie ASP. Aplikacja oparta na platformie NET, która jest oparta na programie .NET Framework 2.0 i nowszych wersjach, aplikacja nieoczekiwanie kończy działanie. W przypadku wystąpienia tego problemu w dzienniku aplikacji nie trzeba rejestrować żadnych informacji o wyjątku, które należy zrozumieć.
Jednak komunikat o zdarzeniu podobny do poniższego przykładu może zostać zarejestrowany w dzienniku systemu. Ponadto w dzienniku aplikacji może zostać zarejestrowany komunikat o zdarzeniu podobny do poniższego przykładu.
Przyczyna
Ten problem występuje, ponieważ domyślne zasady nieobsługiwane wyjątki uległy zmianie w programie .NET Framework 2.0 i nowszych wersjach. Domyślnie zasady nieobsługiwane wyjątki polegają na zakończeniu procesu roboczego.
W programie .NET Framework 1.1 i w programie .NET Framework 1.0 nieobsługiwane wyjątki w wątkach zarządzanych zostały zignorowane. Jeśli nie dołączono debugera w celu przechwycenia wyjątku, nie zdajesz sobie sprawy, że coś jest złe.
ASP.NET używa zasad domyślnych dla nieobsługiwane wyjątki w programie .NET Framework 2.0 i nowszych wersjach. Gdy zgłaszany jest nieobsługiwany wyjątek, asp. Aplikacja oparta na platformie NET nieoczekiwanie kończy działanie.
To zachowanie nie ma zastosowania do wyjątków występujących w kontekście żądania. Tego rodzaju wyjątki są nadal obsługiwane i opakowane przez HttpException
obiekt. Wyjątki występujące w kontekście żądania nie powodują zakończenia procesu roboczego. Jednak nieobsługiwane wyjątki poza kontekstem żądania, takie jak wyjątki w wątku czasomierza lub w funkcji wywołania zwrotnego, powodują zakończenie procesu roboczego.
Rozwiązanie 1
Zmodyfikuj kod IHttpModule
źródłowy obiektu, aby rejestrował informacje o wyjątkach w dzienniku aplikacji. Zarejestrowane informacje będą zawierać następujące informacje:
- Ścieżka katalogu wirtualnego, w której wystąpił wyjątek
- Nazwa wyjątku
- Komunikat
- Ślad stosu
Aby zmodyfikować IHttpModule
obiekt, wykonaj następujące kroki.
Uwaga 16.
Ten kod rejestruje komunikat o typie zdarzenia błędu i źródle zdarzeń ASP.NET 2.0.50727.0 w dzienniku aplikacji. Aby przetestować moduł, zażądaj strony ASP.NET korzystającej z ThreadPool.QueueUserWorkItem
metody w celu wywołania metody, która zgłasza nieobsługiwany wyjątek.
Umieść następujący kod w pliku o nazwie 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); } } }
Zapisz plik UnhandledExceptionModule.cs w folderze
C:\Program Files\Microsoft Visual Studio 8\VC
.Otwórz wiersz polecenia programu Visual Studio.
Wpisz
sn.exe -k key.snk
, a następnie naciśnij ENTER.Wpisz
csc /t:library /r:system.web.dll,system.dll /keyfile:key.snk UnhandledExceptionModule.cs
, a następnie naciśnij ENTER.Wpisz
gacutil.exe /if UnhandledExceptionModule.dll
, a następnie naciśnij ENTER.Wpisz
ngen install UnhandledExceptionModule.dll
, a następnie naciśnij ENTER.Wpisz
gacutil /l UnhandledExceptionModule
, a następnie naciśnij ENTER , aby wyświetlić silną nazwę pliku UnhandledExceptionModule .Dodaj następujący kod do pliku Web.config platformy ASP. Aplikacja oparta na platformie NET.
<add name="UnhandledExceptionModule" type="WebMonitor.UnhandledExceptionModule, <strong name>" />
Rozwiązanie 2
Zmień nieobsługiwane zasady wyjątków z powrotem na domyślne zachowanie, które występuje w programie .NET Framework 1.1 i w programie .NET Framework 1.0.
Uwaga 16.
Nie zalecamy zmiany zachowania domyślnego. Jeśli zignorujesz wyjątki, aplikacja może wyciekać zasoby i porzucić blokady.
Aby włączyć to zachowanie domyślne, dodaj następujący kod do pliku Aspnet.config znajdującego się w następującym folderze:
%WINDIR%\Microsoft.NET\Framework\v2.0.50727
<configuration>
<runtime>
<legacyUnhandledExceptionPolicy enabled="true" />
</runtime>
</configuration>
Stan
Wynika to z ustawienia fabrycznego.
Więcej informacji
Aby uzyskać więcej informacji na temat zmian w programie .NET Framework 2.0, odwiedź stronę Breaking Changes in .NET Framework 2.0 (Istotne zmiany w programie .NET Framework 2.0).