您的位置:首页 > 编程语言 > ASP

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

2011-04-29 13:47 465 查看
http://support.microsoft.com/kb/911816/zh-cn

症状:

如果在 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
页,以调用引发未处理的异常的方法。

将下面的代码放在名为 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

打开 Microsoft Visual Studio 2005 命令提示符窗口。

键入 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。(生成程序集及其依赖项的本机映像,并在本机映像缓存中安装这些映像。
如果指定了 /queue,则操作将排队等待本机映像服务。默认优先级是 3)
键入 gacutil /l UnhandledExceptionModule,然后按
Enter 以显示 UnhandledExceptionModule 文件的强名称。(Lists the contents of the global assembly cache. If you specify the assemblyName parameter, the tool lists only the assemblies matching that name.)
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>



回到顶端
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐