• 在 .NET Framework 2.0 中未处理的异常导致基于 ASP.NET 的应用程序意外退出


    本文摘自微软:http://support.microsoft.com/?id=911816
    问题现象:

    如果在 Microsoft .NET Framework 2.0 上构建的基于 Microsoft ASP.NET 的应用程序中引发未处理的异常,该应用程序将会意外退出。如果出现这个问题,不会在应用程序日志中记录了解此问题所必需的异常信息。

    但是,系统日志中可能会记录类似于以下内容的事件消息:

    事件类型:警告
    事件来源:W3SVC
    事件类别:无
    事件 ID: 1009
    日期: 9/28/2005
    时间:3:18:11
    PM 用户:N/A
    计算机:IIS-SERVER
    描述:
    为应用程序池“DefaultAppPool”提供服务的进程意外终止。进程 ID 是“2548”。进程退出代码是“0xe0434f4d”。

    而且,应用程序日志中可能会记录类似于以下内容的事件消息:

    事件类型:错误
    事件来源:.NET Runtime 2.0 错误报告
    事件类别:无
    事件 ID: 5000
    日期: 9/28/2005
    时间:3:18:02 PM
    用户:N/A
    计算机:IIS-SERVER
    描述:
    EventType clr20r3, P1 w3wp.exe, P2 6.0.3790.1830, P3 42435be1, P4 app_web_7437ep-9, P5 0.0.0.0, P6 433b1670, P7 9, P8 a, P9 system.exception, P10 NIL.

    问题原因:

    出现这个问题的原因在于未处理异常的默认策略在 .NET Framework 2.0 中已发生更改。默认情况下,未处理异常的策略是结束工作进程。

    在 Microsoft .NET Framework 1.1 和 Microsoft .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);
            }

        }
    }
    1.  将 UnhandledExceptionModule.cs 文件保存到下面的文件夹中:
    2. C:\Program Files\Microsoft Visual Studio 8\VC
    3. 打开 Microsoft Visual Studio 2005 命令提示符窗口。
    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>

  • 相关阅读:
    golang书签
    linux每日知识整理
    leetcode动态规划笔记五---双序列型
    leetcode动态规划笔记三---单序列型
    leetcode动态规划笔记二---矩阵型DP
    leetcode动态规划笔记一---一维DP
    linux系统IO操作
    golang知识精要(二)
    ubuntu修改键盘键位映射
    Python 使用 cx_Oracle 第三方库连接操作Oracle数据库
  • 原文地址:https://www.cnblogs.com/philips/p/1759346.html
Copyright © 2020-2023  润新知