asp.net中“线程正被中止”异常的解决方法

 

asp.net中“线程正被中止”异常的解决方法

在项目里负责异常处理部分:异常信息的写入,读取,查看,因此就可以看到各种异常,受益匪浅
看到有N多的“线程正被中止”异常,而且来自同一个页面。
System.Threading.ThreadAbortException: 线程正被中止。
at System.Threading.Thread.AbortInternal()
at System.Threading.Thread.Abort(Object stateInfo) at System.Web.HttpResponse.End()
at System.Web.HttpServerUtility.Transfer(String path, Boolean preserveForm)
at RPM.Page.LogInHR.btnLogin_Click(Object sender, EventArgs e)
in c:/inetpub/wwwroot/rpm_2/page/login/loginhr.aspx.cs:line 363
虽然捕获了,但并没有跳转到错误页面,但这个信息是在错误页面被写入数据库的!
我做了个试验,在异常信息查询页面跳转到异常信息一览页面
引发异常的页面:
try
     {
      // 异常一览页面
      Server.Transfer("../SystemManagement/ErrorReportView.aspx",false);
     }
     catch (Exception ex)
     {
      HttpContext.Current.Session["CurrentError"] = ex.ToString();
      HttpContext.Current.Session["CurrentErrorUrl"] = HttpContext.Current.Request.Url.ToString();
      // 跳转到异常信息显示页面
      HttpContext.Current.Server.Transfer("ErrorReport.aspx",false);
     }
异常信息显示页面对异常的处理:
string errortip = "<h4>" + Resources["MEMO_346"] + "</h4>" + "<br><br>";

      string error =
       "在页面:" + "<br>"
       + (string)Session["CurrentErrorUrl"] +"<br>"
       + "发生了如下异常:" + "<br>"
       + (string)Session["CurrentError"];
    
      // 部署时 不要显示异常信息!
      lblErrorMessage.Text = errortip + error;
      // 写入数据库
      LCW.RPM.BLL.ErrorReport errorReport = new LCW.RPM.BLL.ErrorReport();
      LCW.RPM.Model.ErrorReportInfo errorInfo = new LCW.RPM.Model.ErrorReportInfo();
      errorInfo.Content = error;
      errorInfo.UserName = "sa";
      errorReport.Insert(errorInfo);
也就是说实际上,确实跳转到了异常处理页面,并执行了代码,但没等到页面显示,就又跳到了异常信息一览页面,但此时并没有将刚才的异常查询出来,需要刷新页面才会出来。看来确实存在终止线程的问题
MSDN是这么说的:
ThreadAbortException 的引发条件:对 End 的调用已经终止当前请求。

Redirect 调用End,该方法在完成时引发 ThreadAbortException 异常。

End、Redirect 和Transfer的调用在当前响应提前结束时引发一个 ThreadAbortException。

End(HttpResponse.End )方法的说明:

将当前所有缓冲的输出发送到客户端,停止该页的执行,并引发 Application_EndRequest 事件。

ThreadAbortException:

在调用 Abort方法以销毁线程时,公共语言运行库将引发 ThreadAbortExceptionThreadAbortException 是一种可捕获的特殊异常,但在 catch 块的结尾处它将自动被再次引发。引发此异常时,运行库将在取消线程前执行所有 finally 块。由于线程可以在 finally 块中进行未绑定的计算,因此必须调用Join方法以保证线程已死亡。Join 是一个阻塞调用,它要到线程实际停止执行后才返回。

想不太明白

Update:

看了晓风残月 写的一篇文章 Response.Redirect 与 异常(线程正在中止) ,提到一文

原来    HttpContext.Current.Server.Transfer("ErrorReport.aspx",false);
是把异常挂起了,所以代码照样执行

按照文章试验了一下:

Response.Redirect(url)等同于Response.Redirect(ur,true),有异常

Response.Redirect(url,false),无异常

 

Server.Execute(url)无异常

 

Server.Transfer(url)等同于Server.Transfer(url,true)和Server.Transfer("ErrorReportView.aspx",false);都会出现异常

 

总之,要想避免异常,就用Response.Redirect(url,false)或Server.Execute(url)。

关于这三者的区别,另开新帖说明。

ps:

偶然发现Server.Execute(url)可以实现那种弹出框提示后紧接着跳转页面的需求,而其他两种情况下弹出框提示信息都不会显示。

注:如果使用 try 、catch 处理包含Response.Redirect    语句代码,总是能捕捉到异常:线程正在中止,
其实不仅仅Response.Redirect 会,Response.End 和 Server.Transfer 也是一样的情况,本质的原因的原因是Response.End 方法停止页的执行,并将该执行变换到应用程序的事件管线中的 Application_EndRequest 事件, Response.End 后面的代码行将不执行。通常认为Response.End 方法是线程的非正常结束,因此MS就在内部抛出ThreadAbortException 异常,而Response.Redirect 和 Server.Transfer 这两种方法都在内部调用 Response.End。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值