【问题标题】:ASP.NET exception "Thread was being aborted" causes method to exitASP.NET 异常“线程被中止”导致方法退出
【发布时间】:2010-11-04 02:34:07
【问题描述】:

在下面的代码中,有时someFunctionCall()会产生异常:

线程被中止。

为什么代码块 B 中的代码永远不会运行? ASP.NET 是否为每个方法调用启动一个新线程?我惊讶地发现,当这个异常发生时,块 B 中的代码永远不会运行,方法返回,我的应用程序继续运行。有人可以解释一下吗?

public void method()
{
     // CODE BLOCK A
     //...    

     try 
     {
         someFunctionCall(); // this call is generating thread abort exception
     }
     catch(Exception ex)
     {
         // log exception message
     }

    // CODE BLOCK B
    // ...    
}

【问题讨论】:

    标签: c# .net asp.net


    【解决方案1】:

    对我有用的是增加 IIS 上应用程序池的“空闲超时(分钟)”属性。

    我将它设置为“43200”,这是最大值。

    我还调整了回收设置...

    【讨论】:

      【解决方案2】:

      要解决此问题,请使用以下方法之一: 对于Response.End,调用HttpContext.Current.ApplicationInstance.CompleteRequest 方法而不是Response.End 以绕过代码执行到Application_EndRequest 事件。

      对于Response.Redirect,使用为endResponse 参数传递false 的重载Response.Redirect(String url, bool endResponse),以抑制对Response.End 的内部调用。例如:

      Response.Redirect ("nextpage.aspx", false);
      

      如果您使用此解决方法,则会执行Response.Redirect 后面的代码。 对于Server.Transfer,请改用Server.Execute 方法。

      【讨论】:

        【解决方案3】:

        试试这个方法:

        这是我的扩展方法:

         public static void WriteJSONObject(this HttpResponse response, object content) {
                    response.ContentType = "application/json";
                    response.Write(new JavaScriptSerializer().Serialize(content));
                    response.End();
        
         }
        

        还有逻辑:

        public void RegisterUser() {
            try {
                Response.WriteJSONObject(new { Result = "See hello" });
            } 
            catch (Exception err) {
                if (err.Message != "Thread was being aborted.")
                    Response.WriteJSONObject(new { Result = err.Message });
                else {
                    Response.End();
                }
            }
        }
        

        【讨论】:

        • 这是错误的。您应该从不将异常的Message 与硬编码字符串进行比较。相反,您可以写catch (ThreadAbortException) {} catch (Exception ex) { ... }。此外,如果已经有ThreadAbortException,则调用Response.End 是没有意义的。
        • P.s : 上面的解决方案不像大多数人那样对我有用。不管我做什么都没有用,所以这是我找到的唯一解决方案,而且效果很好。
        • 我并不是说它不起作用;我说这是一个可怕的想法。您的代码正在解决与此问题无关的另一个问题。
        【解决方案4】:

        这是ThreadAbortException;这是一个特殊的异常,会在每个 catch 块结束时自动重新抛出,除非您调用 Thread.ResetAbort()

        Response.EndResponse.Redirect 等ASP .Net 方法(除非您传递false)抛出此异常以结束当前页面的处理;您的 someFunctionCall() 可能正在调用其中一种方法。

        ASP .Net 自己处理这个异常并调用ResetAbort 继续处理。

        【讨论】:

        • 那么我怎样才能让它忽略该异常并继续执行块 B 中的代码?
        • 您确定要这样做吗?如果 someFunctionCall 正在重定向或结束响应,您可能不应该继续它
        • someFunctionCall 有什么作用?
        • 它对第 3 方供应商进行 XML-RPC 调用。没有响应结束或重定向。如果它是旧版本的 XML-RPC API,我想忽略它并继续使用默认值。
        • 在 catch 块中调用 Thread.ResetAbort。另外,询问供应商异常是什么。异常的堆栈跟踪是什么?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-05-22
        • 2015-12-05
        • 1970-01-01
        • 2011-05-27
        • 1970-01-01
        • 1970-01-01
        • 2014-07-27
        相关资源
        最近更新 更多