未處理的例外狀況會導致 ASP。以 NET 為基礎的應用程式在 .NET Framework 中意外結束
本文可協助您解決未處理的例外狀況導致 ASP 的問題。以 NET 為基礎的應用程式會在 .NET Framework 中意外結束。
原始產品版本:.NET Framework 4.5
原始 KB 編號: 911816
注意事項
本文適用於 Microsoft .NET Framework 2.0 和所有更新版本。
徵狀
當 ASP 中擲回未處理的例外狀況時。建置在 .NET Framework 2.0 和更新版本之上的 NET 型應用程式,應用程式意外地結束。 發生此問題時,應用程式記錄中不會記錄您必須了解問題的例外狀況資訊。
不過,類似下列範例的事件訊息可能會記錄在系統記錄檔中。 此外,類似下列範例的事件訊息可能會記錄在應用程式記錄檔中。
原因
發生此問題的原因是,.NET Framework 2.0 和更新版本中未處理例外狀況的默認原則已變更。 根據預設,未處理例外狀況的原則是結束背景工作進程。
在 .NET Framework 1.1 和 .NET Framework 1.0 中,會忽略 Managed 線程上未處理的例外狀況。 除非您附加調試程式來攔截例外狀況,否則不會發現發生任何錯誤。
ASP.NET 會針對 .NET Framework 2.0 和更新版本中未處理的例外狀況使用默認原則。 當擲回未處理的例外狀況時,ASP。以 NET 為基礎的應用程式意外結束。
此行為不適用於在要求內容中發生的例外狀況。 這些類型的例外狀況仍由 HttpException
對象處理和包裝。 在要求內容中發生的例外狀況不會導致背景工作進程結束。 不過,在要求內容之外未處理的例外狀況,例如定時器線程或回調函式中的例外狀況,會導致背景工作進程結束。
解決方案 1
修改物件的 IHttpModule
原始程式碼,使其將例外狀況資訊記錄到應用程式記錄檔。 記錄的資訊將包含下列專案:
- 發生例外狀況的虛擬目錄路徑
- 例外狀況名稱
- 訊息
- 堆疊追蹤
若要修改 IHttpModule
物件,請遵循下列步驟。
注意事項
此程式代碼會在應用程式記錄檔中記錄錯誤 事件類型 和 事件來源為 ASP.NET 2.0.50727.0 的訊息。 若要測試模組,請要求使用 ThreadPool.QueueUserWorkItem
方法的 ASP.NET 頁面來呼叫擲回未處理例外狀況的方法。
將下列程式代碼放在名為 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); } } }
將 UnhandledExceptionModule.cs 檔儲存至
C:\Program Files\Microsoft Visual Studio 8\VC
資料夾。開啟 Visual Studio 命令提示字元。
輸入
sn.exe -k key.snk
,然後按 ENTER。輸入
csc /t:library /r:system.web.dll,system.dll /keyfile:key.snk UnhandledExceptionModule.cs
,然後按 ENTER。輸入
gacutil.exe /if UnhandledExceptionModule.dll
,然後按 ENTER。輸入
ngen install UnhandledExceptionModule.dll
,然後按 ENTER。輸入
gacutil /l UnhandledExceptionModule
,然後按 ENTER 以顯示 UnhandledExceptionModule 檔案的強名稱。將下列程式代碼新增至 ASP 的Web.config 檔案。以 NET 為基礎的應用程式。
<add name="UnhandledExceptionModule" type="WebMonitor.UnhandledExceptionModule, <strong name>" />
解決方案 2
將未處理的例外狀況原則變更回在 .NET Framework 1.1 和 .NET Framework 1.0 中發生的默認行為。
注意事項
我們不建議您變更預設行為。 如果您忽略例外狀況,應用程式可能會洩漏資源並放棄鎖定。
若要啟用此預設行為,請將下列程式代碼新增至位於下列資料夾中的 Aspnet.config 檔案:
%WINDIR%\Microsoft.NET\Framework\v2.0.50727
<configuration>
<runtime>
<legacyUnhandledExceptionPolicy enabled="true" />
</runtime>
</configuration>
狀態
產生此錯誤是系統刻意為之。
其他相關資訊
如需 .NET Framework 2.0 中變更的詳細資訊,請造訪 .NET Framework 2.0 的重大變更。
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應