本文可帮助你解决未处理的异常导致基于 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 页。
将以下代码放入名为
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.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 中的中断性更改。