ASP.NET应用程序中的Thread.Abort导致w3wp.exe崩溃

时间:2015-09-01 15:04:33

标签: c# iis windows-10 .net-4.6 threadabortexception

不要在此qustion上设置重复标记 - 它不是关于"为什么会发生ThreadAbortException",它是关于"为什么w3wp.exe进程在ThreadAbortException之后终止& #34;

让我们说我们有简单的Web应用程序,其中包含以下代码示例:

protected void Page_Load(object sender, EventArgs e)
{
    Response.Redirect("http://google.com");
}

事实上,这意味着(见Is Response.End() considered harmful?):

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)上,此代码仅生成ThreadAborted异常,但进程继续工作(重定向执行)。

有人可以检查这个样本并解释发生了什么吗?

更新 这里有一些与此问题相关的Windows事件日志。

日志#1

  

发生了未处理的异常,并且该过程已终止。

     

申请ID:/ LM / W3SVC / 1 / ROOT / AS

     

进程ID:6700

     

异常:System.Threading.ThreadAbortException

     

消息:线程正在中止。

     

StackTrace:at   System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest   wr,HttpContext context)at   System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr的   rootedObjectsPointer,IntPtr nativeRequestContext,IntPtr moduleData,   Int32标志)在   System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(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: 

4 个答案:

答案 0 :(得分:4)

我能够在安装了.NET 4.6的Server 2008r2上重现该问题。

我怀疑你们其他人遇到了同样的问题; ThreadAbortExceptions在事件日志中杀死了应用程序池(虽然任何未处理的异常会导致我的问题;但这可能只是一个全局异常处理程序捕获它并完成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

答案 1 :(得分:3)

到目前为止,我只有一个解决方案:

    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

注意,只有&#34;返回&#34;在某些情况下是不够的(例如使用递归调用),在某些情况下,您可能需要避免使用&#34; return&#34; (使用try-finally结构)

答案 2 :(得分:2)

我重启安装Windows更新后,今天在Windows 8.1上遇到了同样的问题。

问题在于我通过添加useLegacyJit DWORD并将其设置为1(请参阅due to this issue)在注册表中Method #3手动禁用了RyuJIT。但是其中一个更新在同一个位置创建了UseRyuJIT密钥,并将其设置为1,这显然让ASP.NET非常困惑。

解决方案是将useLegacyJit设置为0并发出iisreset。在那之后,世界上一切都很好。

当我调试!clrstack转储时,

WinDbg&#39; s w3wp.exe显示以下帧。也许这会帮助其他人在谷歌搜索解决方案时遇到同样的错误:

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]

答案 3 :(得分:0)

我在Win7 SP1上遇到过同样的问题。 Web应用程序编译为.net 4.5.2并在.net 4.6上运行。我还没有弄乱useLegacyJit或useRyuJIT注册表标记。

关闭&#34;启用32位应用程序&#34;在我的应用域上被不必要地设置为启用。禁用它可以解决问题。