解决asp.net中 jquery ajax调用一般处理程序ashx出现"正在中止线程"异常

项目中使用JQuery Ajax调用ashx一般处理程序的时候出现无法获取数据的问题,经排查是由于AJAX发送请求引发了ThreadAbortException异常,提示的错误信息是“正在中止线程”。

 

引发该异常的原因是由于ajax调用一般处理程序.ashx获取数据时,在public void ProcessRequest(HttpContext context)方法中使用了try catch的异常捕获,并且还使用context.Response.End(),最终导致线程出现中止。这个异常在调试中可能显示不出来,只会提示这个信息:由于代码已经过优化或者本机框架位于调用堆栈之上,无法计算表达式的值。 

出现错误的代码如下,大家可以在程序上测试下:

ajax代码:

<scirpt  type="text/javascript">
 $(function () {
$.ajax({
        type: "GET",
        url: "/Ajax/test.ashx",        
        async: false,
        success: function (data) {alert(data);},
        error: function (ex) {alert(ex.error);}
    });
});
</script>

ashx 一般处理程序代码:

public void ProcessRequest(HttpContext context)
        {            
            try
            {                 
                context.Response.Write("执行成功");
                context.Response.End();
            }
            catch (ThreadAbortException tae)
            {
                //这里提示正在中止线程
                context.Response.Write(tae.Message);
                context.Response.End();
            }
            catch (Exception ex)
            {                                
                context.Response.Write(ex.Message);
                context.Response.End();
            }            
        }

解决思路有两个:

1、不要在try catch中使用context.Response.End(),在finally中或者放置在try catch外使用。 

public void ProcessRequest(HttpContext context)
        {
            try
            {
                context.Response.Write("执行成功");
            }
            catch (ThreadAbortException tae)
            {             
                context.Response.Write(tae.Message);
            }
            catch (Exception ex)
            {
                context.Response.Write(ex.Message);
            }
            finally
            {
                //将context.Response.End()移至到finally中使用
                //或者在try catch外使用
                context.Response.End();
            }
        }

2、不要使用try catch,将逻辑代码放置在BLL业务逻辑层中。 


另外出现此问题是由于ASP.NET 设计上的问题,具体可查看微软官方对于此问题的描述:ThreadAbortException Occurs If You Use Response.End, Response.Redirect, or Server.Transfer (点击此处为中文翻译链接)

 

我们可以从中发现,不仅仅是Response.End会引发这个问题,Response.Redirect和Server.Transfer方法也会引发该问题。文章中说造成这种原因是由于:

Response.End方法结束执行页,并将执行切换到应用程序的事件管道中的Application_EndRequest事件。Response.End之后的代码行不会被执行。因为这两种方法都会内部调用Response.End , Response.Redirect和Server.Transfer的方法中发生此问题。


官文文档中还有另外一种解放方法:

若要变通解决此问题,请使用下列方法之一:

  • 对于Response.End,调用HttpContext.Current.ApplicationInstance.CompleteRequest方法,而不是Response.End能够绕过到Application_EndRequest事件的代码执行。
  • 对于Response.Redirect,使用重载,传递false以取消内部调用Response.End的endResponse参数的Response.Redirect (url 字符串、 布尔值 endResponse) 。
    • 例如:Response.Redirect ("nextpage.aspx", false);
    • 如果您使用此替代方法,遵循Response.Redirect的代码执行。
  • 对于Server.Transfer,而是使用Server.Execute方法。



原创文章,作者:kepupublish,如若转载,请注明出处:https://blog.ytso.com/98311.html

(0)
上一篇 2021年8月21日
下一篇 2021年8月21日

相关推荐

发表回复

登录后才能评论