很多帖子都分析過try-catch的機制,以及其對效能的影響。
但是並沒有證據證明,try-catch過於損耗了系統的效能,尤其是在託管環境下。記得園子裡有位網友使用stopwatch分析過try-catch在不同情況下,與無try-catch的**相比,**執行的時間指標,結果並沒有很大差異。
下面我來結合il分析一下try-catch吧。
● 機制分析
.net 中基本的異常捕獲與處理機制是由try…catch…finally塊來完成的,它們分別完成了異常的監測、捕獲與處理工作。乙個try塊可以對應零個或多個catch塊,可以對應零個或乙個finally塊。不過沒有catch的try似乎沒有什麼意義,如果try對應了多個catch,那麼監測到異常後,clr會自上而下搜尋catch塊的**,並通過異常過濾器篩選對應的異常,如果沒有找到,那麼clr將沿著呼叫堆疊,向更高層搜尋匹配的異常,如果已到堆疊頂部依然沒有找到對應的異常,就會丟擲未處理的異常了,這時catch塊中的**並不會被執行。所以距離try最近的catch塊將最先被遍歷到。
如有以下**:
複製** **如下wvjrqmg:
try
catch (formatexception ex1)
catch (nullreferenceexception ex2)
finally
對應il如下:
複製** **如下:
.method private hidebysig instance void form1_load(object sender,
class [mscorlib]system.eventargs e) cil managed
// end of method form1::form1_load
末尾的幾行**揭示出il是怎樣處理異常處理的。最後三行的每乙個item被稱作exception handing clause,ehc組成exception handing table,eht與正常**之間由ret返回指令隔開。
可以看出,formatexception排列在eht的第一位。
當**成功執行或反之而返回後,clr會遍歷eht:
1. 如果丟擲異常, clr會根據丟擲異常的**的「位址」找到對應的ehc(il_0001 to il_0010為檢測**的範圍),這個例子中clr將找到2條ehc,formatexception會最先被遍歷到,且為適合的ehc。
2. 如果返回的程式設計客棧**位址在il_0001 to il_0029內,那麼還會執行finally handler 即il_0029 to il_0033中的**,不管是否因成功執行**而返回。
事實上,catch與finally的遍歷工作是分開進行的,如上文所言,clr首先做的是遍歷catch,當找到合適的catch塊後,再遍歷與之對應finally;而且這個過程會遞迴進行至少兩次,因為編譯器將c#的try…catch…finally翻譯成il中的兩層巢狀。
當然如果沒有找到對應的catch塊,那麼clr會直接執行finally,然後立即中斷所有執行緒。finally塊中的**肯定會被執行,無論try是否檢測到了異常。
改進建議
由上面的內容可以得出:
如果使用了「try-catch」,且捕獲到了異常,clr做的只不過是遍歷exception handing table中的catch項;然後再次遍歷exception handing table中的finally項,所用時間幾乎都花費在遍歷exception handing table上;而如果沒有捕獲到異常,clr只是遍歷exception handing table中的finally項,www.cppcns.com所需時間微乎其微。
而「try-catch」遍歷後的執行對應操作所用時間,則根據你的具體**所定,「try-catch」引起的只是監控與觸發,不應將這部分的**時間也算「try-catch」的消耗。
所以,可以從效能和**評審兩方面考慮,一般建議有以下幾點準則:
1.盡量給clr乙個明確的異常資訊,不要使用exception去過濾異常
2.盡量不要將try…catch寫在迴圈中
3. try盡量少的**,如果有必要可以使用多個catch塊,並且將最有可能丟擲的異常型別,書寫在距離try最近的位置
4.不要只宣告乙個exception物件,而不去處理它。這樣做白白增加了exception handing table的長度。
5.使用效能計數器實用工具的「clr exceptions」檢測異常情況,並適當優化
6.使用成員的try-parse模式,如果丟擲異常,那麼用false代替它
結論,try-catch雖然會消費一點時間,但程式人員大可不必談虎色變,通過上面的分析,與其說「try-catch」會損耗或影響效能,不如說「try-catch」與其他**一樣,只是效能的普通消費者,但出於**書寫評審方面的考慮,還是盡量關照一下「try-catch」吧。
本文標題: c#中try-catch語句真的影響程式效能嗎?
本文位址:
C 異常處理 try catch語句
以下 是個人用來學習記錄,功能是看懂try catch語句可以看懂在搜尋呼叫棧來尋找乙個異常處理程式的順序。功能 看懂搜尋try catch語句搜尋呼叫棧尋找乙個異常處理程式的順序 using system 包含兩個方法的型別,其中b型別是異常的 class myclass catch nullre...
trycatch中return語句如何執行
測試 如下 1 package reviewtest 23 4 classname returntest 5 description 測試return在trycatch中的執行6 author kingram 7 date 2018年7月27日8 9 10public class returntes...
c 中try catch的用法
在c 中,可以直接丟擲異常之後自己進行捕捉處理,如 這樣就可以在任何自己得到不想要的結果的時候進行中斷,比如在進行資料庫事務操作的時候,如果某乙個語句返回sql error則直接丟擲異常,在catch塊中進行事務回滾 include include using namespace std int m...