ThreadAbortException When Response.End()

以下這段Code,如果getIdFromDb()傳回"1"時,顯示結果為何?

是"ID=1"嗎? 錯!! 後方還會接上"ERROR:Thread was being aborted."

   15 protected void Page_Load(object sender, EventArgs e)

   16 {

   17     try

   18     {

   19         string id = getIdFromDb();

   20         if (id != null)

   21         {

   22             Response.Write("ID=" + id);

   23             Response.End();

   24         }

   25     }

   26     catch (Exception ex)

   27     {

   28         Response.Write("<br>ERROR:" + ex.Message);

   29         Response.End();

   30     }

   31     //Do something when id not found

   32     //....

   33 }

我寫了一個元件,其中有個Complete() Method會直接輸出XML,為了防止後方又被呼叫方Response.Write多餘的文字破壞XML結構,我在Method中呼叫了HttpContext.Current.Reponse.End(),結果呼叫端用try...catch包住Complete(),即使正常執行完成,卻老會在Exception中觸發ThreadAbortException。

Goggle了一下,才發現我並不真的了解Response.End。依據微軟KB 312629的說明,Response.End、Server.Transfer、Response.Redirect被呼叫時,本來就會觸發此一ThreadAbortException(我倒是不理解為何正常的執行流程,卻要夾帶一個Exception,某非是某個SD人員的鋸箭之舉),因此若在try ... catch中包含了這三個執行指令,就會因為ThreadAbortException而跑入catch區段。

依KB的說法,要解決方法包含: 1) 用HttpContext.Current.ApplicationInstance.CompleteRequest();取代Response.End(); 2) 如果是Server.Transfer,可用Server.Execute代替 3) 考慮改用Response.Redirect("...", false) (有程式會繼續往下跑的後遺症)

我還想到的另一種方法是try ... catch時去catch ThreadAbortException後Do Nothing,只是這犯了把Exception當正常邏輯的效能禁忌,所以不應在考量之列。

歡迎推文分享:
Published 09 March 2007 01:51 PM 由 Jeffrey
Filed under:
Views: 26,099



意見

# chicken said on 09 March, 2007 06:00 AM

哈, 這個問題我也碰過... 明明跟 ASP 一樣的 API, 但是行為卻跟 ASP 不一樣... -_- 有時後這個 exception 不會輸出到 browser 上, 只會在 windows event log 留下記錄.. 熊熊看到 log 一時還真摸不清是啥問題

# kennyshu said on 18 May, 2009 01:24 PM

真是相見恨晚...

我debug了好久就是不知道為何老是catch到Thread was being aborted.這個錯誤訊息,原來是我的try catch裡面有很多Response.Redirect(),終於解決了我的疑惑!

# Robin Lin said on 08 February, 2012 01:36 AM

經過測試HttpContext.Current.ApplicationInstance.CompleteRequest仍會往下執行後面的程式,所以個人覺得可以使用 retrun 來代替 Response.End,應該就不會出現Exception。

# Robin Lin said on 08 February, 2012 02:11 AM

更正:

HttpContext.Current.ApplicationInstance.CompleteRequest會中止網頁其他後續事件的引發,所應該是使用HttpContext.Current.ApplicationInstance.CompleteRequest後面在加上return來代替Response.End

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 
(提醒: 因快取機制,您的留言幾分鐘後才會顯示在網站,請耐心稍候)

5 + 3 =

搜尋

Go

<March 2007>
SunMonTueWedThuFriSat
25262728123
45678910
11121314151617
18192021222324
25262728293031
1234567
 
RSS
創用 CC 授權條款
【廣告】
twMVC
最新回應

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


Syndication