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

8 c# iis threadabortexception windows-10 .net-4.6

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

假设我们有简单的Web应用程序,其代码示例如下:

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

事实上这意味着什么(参见Response.End()被认为是有害的?):

protected void Page_Load(object sender, EventArgs e)
{
    ...response write some data...
    System.Threading.Thread.CurrentThread.Abort();
}
Run Code Online (Sandbox Code Playgroud)

在我的计算机(Windows 10 Pro + IIS)上,此代码导致IIS池进程终止,错误代码为0x0(重定向不执行).在其他计算机(不是Windows 10)上,此代码仅生成ThreadAborted异常,但进程继续工作(重定向执行).

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

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

记录#1

发生未处理的异常,并终止该过程.

应用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 flags)

记录#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: 
Run Code Online (Sandbox Code Playgroud)

Mis*_*mbu 5

我能够在安装了 .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

知识库修补程序: https ://support.microsoft.com/en-us/kb/3098786


小智 4

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

    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();
        }
    }
Run Code Online (Sandbox Code Playgroud)

然而,这迫使我确保在它之后不会执行任何代码:

...some code
response.RedirectSafe(url);
return; //<-- important
...some more code
Run Code Online (Sandbox Code Playgroud)

请注意,在某些情况下(例如递归调用)仅“返回”是不够的,并且在某些情况下您可能需要避免使用“返回”(使用 try-finally 结构)