ASP.NET应用程序中的Thread.Abort导致w3wp.exe崩溃
请不要在此qustion上设置重复标志 – 它不是“为什么发生ThreadAbortException”,它是关于“为什么w3wp.exe进程在ThreadAbortException之后终止”。
假设我们有简单的Web应用程序,其中包含以下代码示例:
protected void Page_Load(object sender, EventArgs e) { Response.Redirect("http://google.com"); }
事实上这意味着什么(参见Response.End()被认为有害吗? ):
protected void Page_Load(object sender, EventArgs e) { ...response write some data... System.Threading.Thread.CurrentThread.Abort(); }
在我的计算机(Windows 10 Pro + IIS)上,此代码导致IIS池进程终止,错误代码为0x0(重定向不执行)。 在其他计算机(不是Windows 10)上,此代码仅生成ThreadAbortedexception,但进程继续工作(重定向执行)。
有人可以检查这个样本并解释发生了什么吗?
更新这里有一些与此问题相关的Windows事件日志。
记录#1
发生未处理的exception并终止该过程。
应用ID:/ LM / W3SVC / 1 / ROOT / AS
进程ID:6700
例外:System.Threading.ThreadAbortException
消息:线程正在中止。
StackTrace:位于System.Web.Hosting.PipelineRuntime.ProcessRequestNotification的System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr rootedObjectsPointer,IntPtr nativeRequestContext,IntPtr moduleData,Int32标志)的System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr,HttpContext context) (IntPtr rootedObjectsPointer,IntPtr nativeRequestContext,IntPtr moduleData,Int32标志)
记录#2
Faulting application name: w3wp.exe, version: 10.0.10240.16384, time stamp: 0x559f3dad Faulting module name: KERNELBASE.dll, version: 10.0.10240.16384, time stamp: 0x559f3b2a Exception code: 0xe0434352 Fault offset: 0x000b3e28 Faulting process id: 0x1a2c Faulting application start time: 0x01d0e4b1b3ed01cb Faulting application path: C:\WINDOWS\SysWOW64\inetsrv\w3wp.exe Faulting module path: C:\WINDOWS\SYSTEM32\KERNELBASE.dll Report Id: 23b5298d-3b36-49c7-a294-de9c864b703f Faulting package full name: Faulting package-relative application ID:
我能够在安装了.NET 4.6的Server 2008r2上重现该问题。
我怀疑你们其他人遇到了同样的问题; ThreadAbortExceptions在事件日志中杀死了应用程序池(虽然任何未处理的exception都会导致我的问题;但这可能只是一个全局exception处理程序捕获它并完成Response.End或Redirect)。 转储堆栈跟踪也与Ian的答案匹配。
为此问题打开了MS Connect故障单,最近的KB修补程序为我解决了该问题。
连接文章: https : //connect.microsoft.com/VisualStudio/feedback/details/1605438/disabling-ryujit-breaks-asp-net
KB修补程序: https : //support.microsoft.com/en-us/kb/3098786
到目前为止,我有唯一的解决方案:
static class WebExtensions { public static void EndSafe(this HttpResponse response) { response.Flush(); response.SuppressContent = true; HttpContext.Current.ApplicationInstance.CompleteRequest(); } public static void RedirectSafe(this HttpResponse response, string url) { response.Redirect(url, false); HttpContext.Current.ApplicationInstance.CompleteRequest(); } }
然而,这迫使我确保在它之后不会执行任何代码:
...some code response.RedirectSafe(url); return; //<-- important ...some more code
注意,在某些情况下只有“返回”是不够的(例如使用递归调用),在某些情况下,您可能需要避免使用“return”(使用try-finally结构)
在重新启动安装Windows更新后,我今天在Windows 8.1上遇到了同样的问题。
问题是我在注册表中手动禁用了RyuJIT, 因为这个问题 ,通过添加useLegacyJit
DWORD并将其设置为1(参见方法#3 )。 但是其中一个更新在同一个位置创建了UseRyuJIT
键,并将其设置为1,这显然让ASP.NET非常困惑。
解决方案是将useLegacyJit
设置为0并发出iisreset
。 在那之后,世界上一切都很好。
当我调试w3wp.exe
转储时,WinDbg的!clrstack
显示以下帧。 也许这会帮助其他人使用谷歌搜索解决方案的同样错误:
000000ef9892be98 00007ffa0e2d1fea [HelperMethodFrame: 000000ef9892be98] 000000ef9892bf80 00007ff99d776588 System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32) 000000ef9892df90 00007ff9fc172345 [FaultingExceptionFrame: 000000ef9892df90] 000000ef9892e490 00007ff99d7796c0 System.Web.HttpRuntime.ProcessRequestNotificationPrivate(System.Web.Hosting.IIS7WorkerRequest, System.Web.HttpContext) 000000ef9892e520 00007ff99d777377 System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32) 000000ef9892e700 00007ff99d77655a System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32) 000000ef9892e740 00007ff99d775c11 DomainNeutralILStubClass.IL_STUB_ReversePInvoke(Int64, Int64, Int64, Int32) 000000ef9892ef58 00007ff9fc100b4e [InlinedCallFrame: 000000ef9892ef58] System.Web.Hosting.UnsafeIISMethods.MgdIndicateCompletion(IntPtr, System.Web.RequestNotificationStatus ByRef) 000000ef9892ef58 00007ff99d78cc1b [InlinedCallFrame: 000000ef9892ef58] System.Web.Hosting.UnsafeIISMethods.MgdIndicateCompletion(IntPtr, System.Web.RequestNotificationStatus ByRef) 000000ef9892ef30 00007ff99d78cc1b DomainNeutralILStubClass.IL_STUB_PInvoke 000000ef9892f000 00007ff99d77756c System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32) 000000ef9892f1e0 00007ff99d77655a System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32) 000000ef9892f220 00007ff99d775c11 DomainNeutralILStubClass.IL_STUB_ReversePInvoke(Int64, Int64, Int64, Int32) 000000ef9892f418 00007ff9fc100da3 [ContextTransitionFrame: 000000ef9892f418]
我在Win7 SP1上遇到了同样的问题。 Web应用程序编译为.net 4.5.2并在.net 4.6上运行。 而且我没有弄乱useLegacyJit或useRyuJIT注册表标志。
在我的应用程序域中,“启用32位应用程序”被不必要地设置为“已启用”。 禁用它可以解决问题。