前幾天在博問中看到一個問題——Response.End()後,是否中止執行?MVC與WebForm不一致。看到LZ的描述後,雖然奇怪於爲什麼用Response.End()而不用return方式去控制流程,但基於本身以往的認識,仍是回答了說須要return。web
由於以往的開發過程當中,雖然沒有用過Response.End()的方式像LZ所說地那樣「方便地從多層調用中退出」,可是始終是認爲Response.End()是不能終止其後代碼執行的,思惟路線大概是:Response.End()只是結束了HTTP返回流的寫入,可是代碼依然沒有return啊,例如Page_Load中使用了Response.End(),可是這個方法並無被跳出/終止。mvc
以後LZ編輯了問題,繼續提到了問題沒有解決,又附帶了僞代碼但願你們幫忙改進書寫方式。直到此時,因爲本身的思惟慣性,我依然我沒有去寫DEMO去驗證對比webform和mvc下的Response.End(),簡單地用主動throw new Exception的方式寫出了MVC下「好看一點」的代碼。app
以後在回覆中,LZ再次重複了Response.End()確實在webform和mvc中存在差別,我抱着試一試地心態測了一個療程。真的有點吃驚,Reponse.End()在webfrom和ASP.NET MVC下的表現確實是不一樣的!post
ASP.NET MVC代碼:this
public ActionResult Index() { Method0(); Method1(); Method2(); Response.Write("All methods success."); return View("I don't think so."); } private void Method0() { Debug.WriteLine("Method 0 process..."); bool flag = true; if (!flag) { Response.Write("Method 0 failure."); Response.End(); } } private void Method1() { Debug.WriteLine("Method 1 process..."); bool flag = false; if (!flag) { Response.Write("Method 1 failure."); Response.End(); } } private void Method2() { Debug.WriteLine("Method 2 process..."); bool flag = false; if (!flag) { Response.Write("Method 2 failure."); Response.End(); } }
web頁面顯示:google
調試信息輸出:spa
Response.End()後的代碼繼續執行,這與以前的認識是沒有出入的,接下來看webform。3d
Webform代碼:調試
protected void Page_Load(object sender, EventArgs e) { Method0(); Method1(); Method2(); Response.Write("All methods success."); } private void Method0() { Debug.WriteLine("Method 0 process..."); bool flag = true; if (!flag) { HttpContext.Current.Response.Write("Method 0 failure."); System.Web.HttpContext.Current.Response.End(); } } private void Method1() { Debug.WriteLine("Method 1 process..."); bool flag = false; if (!flag) { HttpContext.Current.Response.Write("Method 1 failure."); System.Web.HttpContext.Current.Response.End(); } } private void Method2() { Debug.WriteLine("Method 2 process..."); bool flag = true; if (!flag) { HttpContext.Current.Response.Write("Method 2 failure."); System.Web.HttpContext.Current.Response.End(); } }
web頁面輸出:code
調試信息:
web頁面的輸出一致,調試窗口那裏但是大不同。webform並未接着執行Response.End()後的代碼,由於拋出了一個ThreadAbortException異常。這時候,我首先想到的是ASP.NET MVC下的Response對象類型是否和ASP.NET不一樣,致使他們的處理方式不一樣。
後來發現雖然ASP.NET MVC中的Response類型是HttpResponseBase,可是顯式地去調用System.Web.Context.Current.Response.End()結果依舊。經過Reflector查看ASP.NET MVC下HttpResponseBase的實現類HttpResponseWrapper,End方法的實現如圖,this_httpResponse是HttpResponse的私有變量。
查到這兒思路一度中斷,只好回頭去對比調試信息中的表現,從ThreadAbortException這個異常入手,發如今ASP.NET MVC中先調用Response.End(),再調用Thread.CurrentThread.Abort()能夠達到webform下調用Response.End()的效果。固然其餘異常也能模擬,可是此時發現了一個小問題,就是拋出普通異常的時候和拋出ThreadAbortException異常略有不一樣。
普通異常的彈出窗口:
調試信息輸出:
ThreadAbortException異常沒有彈出那個窗口,調試信息中也多了一條信息。
是因爲ThreadAbortException是SystemException(系統異常)被特殊對待了嗎?
這只是一個衍生出來的疑問,繼續剛纔的問題,用ThreadAbortException和ASP.NET MVC做爲關鍵字去google搜索,在Will保哥的博客中獲得瞭解答!
通過保哥的指點,經過Reflector去查看源碼,證明了是_timeoutState的做用。
HttpResponse.End中代碼:
IsInCancellablePeriod屬性:
問題獲得瞭解決!~可是我還有一個小疑問,也就是從Reflector中看到End方法的源碼,IsInCancellablePeriod是bool類型,可是卻判斷是否等於null。這怎麼也是不合適的吧,是Reflector的解析錯誤仍是其餘緣由致使的呢?