未處理的例外狀況會導致 ASP.NET 基礎應用程式在 .NET Framework 中意外結束

本文可協助您解決此問題:未處理的例外狀況會導致 ASP.NET 基礎的應用程式在 .NET Framework 中意外終止。

原始產品版本:  .NET Framework 4。5
原始 KB 編號:  911816

注意

本文適用于 Microsoft .NET Framework 2.0 和所有更新的版本。

徵狀

在 .NET Framework 2.0 和更新版本所建立的 ASP.NET 型應用程式中引發未處理的例外狀況時,應用程式會意外退出。 發生此問題時,就不會在應用程式記錄檔中記錄瞭解問題所需的例外狀況資訊。

不過,與下列範例類似的事件訊息可能會記錄在系統記錄檔中。 此外,類似下列範例的事件訊息可能會記錄在應用程式記錄檔中。

原因

發生此問題的原因是,在 .NET Framework 2.0 和更新版本中,未處理之例外狀況的預設原則已變更。 根據預設,未處理之例外狀況的原則是結束工作者進程。

在 .NET Framework 1.1 及 .NET Framework 1.0 中,忽略受管理的執行緒上未經處理的例外狀況。 除非您已附加偵錯工具來捕捉例外狀況,否則您不會發現有任何錯誤。

ASP.NET 會在 .NET Framework 2.0 和更新版本中使用未處理之例外狀況的預設原則。 當引發未處理的例外狀況時,ASP.NET 基礎的應用程式會意外退出。

這種行為不適用於要求內容中發生的例外狀況。 這類例外狀況仍會透過物件處理及封裝 HttpException 。 在要求的內容中發生的例外狀況未導致工作者進程結束。 不過,要求的上下文以外的未處理的例外狀況(如計時器執行緒或回呼函數中的例外狀況)會導致工作者進程結束。

解決方法1

修改物件的原始程式碼, IHttpModule 使其會將例外狀況資訊記錄至應用程式記錄檔。 記錄的資訊將包含下列專案:

  • 發生例外狀況的虛擬目錄路徑
  • 例外狀況名稱
  • 郵件
  • 堆疊追蹤

若要修改 IHttpModule 物件,請遵循下列步驟。

注意

這段程式碼會記錄事件種類為錯誤的郵件,以及應用程式記錄檔中ASP.NET 2.0.50727.0 的事件來源。 若要測試模組,請要求使用 ThreadPool.QueueUserWorkItem 方法呼叫會引發未處理之例外狀況的方法的 ASP.NET 網頁。

  1. 將下列程式碼放在名為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. UnhandledExceptionModule.cs檔案儲存至 C:\Program Files\Microsoft Visual Studio 8\VC 資料夾。

  3. 開啟 Visual Studio 命令提示字元。

  4. 類型 sn.exe -k key.snk ,然後按enter

  5. 類型 csc /t:library /r:system.web.dll,system.dll /keyfile:key.snk UnhandledExceptionModule.cs ,然後按enter

  6. 類型 gacutil.exe /if UnhandledExceptionModule.dll ,然後按enter

  7. 類型 ngen install UnhandledExceptionModule.dll ,然後按enter

  8. 類型 gacutil /l UnhandledExceptionModule ,然後按Enter顯示UnhandledExceptionModule檔案的強式名稱。

  9. 將下列程式碼加入 ASP.NET 型應用程式的Web.config檔。

    <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 中的重大變更