999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

.Net應用異常處理研究

2018-02-19 18:27:15葉信子
機械制造 2018年12期
關鍵詞:程序機制

□ 葉信子

上海維宏電子科技股份有限公司 上海 200140

1 .Net異常處理機制

人們總是希望編寫出優秀的代碼,以便在生產環境中穩定而持久的運行。然而,不同的客戶所處的環境各不相同,很難保證代碼一直正確運行。因此,工程項目中,代碼的編寫需要更加注重穩定性、容錯性和擴展性。

一般而言,程序的容錯性主要體現在對于異常的處理上。應用程序拋出的異常,如果沒有得到及時的處理,公共語言運行庫(CLR)會自動停止該應用程序的運行。在處理異常的過程中,可以在線程中捕獲這個異常進行處理,然后繼續在另一個線程中重新拋出處理后的異常,以便堆棧的上一級繼續處理該異常。在異常發生時,CLR會在發生異常的堆棧上,由下往上依次查找對應類型異常的catch塊。如果找到了對應的catch塊,那么將異常交由該catch塊處理。處理完成后,應用程序繼續運行。否則,該異常將被視為未經處理的異常。CLR在任何地方檢測到未經處理的異常時,都會立即終止進程,導致應用程序崩潰。

.Net標準的異常處理過程通常由try、catch、finally三個代碼塊完成,他們之間可以相互嵌套,組合起來處理系統的各種異常。

2 代碼塊介紹

2.1 try塊

try塊是異常處理必需的代碼塊,這一代碼塊內部通常包含可能拋出異常的代碼。try塊還可以用來清理系統資源,使系統從異常中恢復過來。每個try塊后面必須跟有至少一個catch或finally塊。

2.2 catch塊

catch塊僅在對應的try塊拋出異常后才會執行。若未發生任何異常,系統會跳過所有catch塊中的內容,繼續向下執行。

catch塊需要顯示所處理異常的類型。所有的異常均繼承自System.Exception。因此,catch塊后面的異常類型可以直接寫System.Exception。但是,為了能夠更好地處理不同類型的異常,仍然應該在catch塊后面放上具體的異常類型,以便CLR在異常發生后,能夠匹配到類型相同的catch塊執行。

2.3 finally塊

finally塊中的內容,無論是否發生異常都會執行。通常而言,finally塊中的代碼用來清理try塊中的資源。finally塊不是必需的,但如果需要用finally塊,那么其必須在所有的catch塊之后,并且一個try塊僅能有一個finally塊。

總體而言,這三個代碼塊是.Net提供的異常處理機制的基礎。在try塊中嘗試執行一些代碼。如果發生了錯誤,那么需要在catch塊中進行處理,以便從錯誤中恢復并繼續執行?;蛘咄ㄟ^catch塊進行補償,來撤銷一些狀態更改,并向調用者上報錯誤。最終,通過finally塊確保清理操作無論如何都能執行。

3 在.Net中執行非托管代碼

.Net程序需要在CLR虛擬機中運行,屬于托管代碼。使用C或C++所編寫的組件,可以直接訪問和修改內存,屬于非托管代碼。托管代碼和非托管代碼的運行機制存在差異,導致非托管代碼無法在托管代碼中使用。因此.Net推出了P/Invoke機制,這實際上是一種函數調用機制,可以消除.Net托管代碼和非托管代碼之間的鴻溝。

在.Net平臺開發出來前,在Windows平臺工作的程序員,基于Win32 API花費了大量精力編寫各種庫和com等非托管組件。為了避免程序重復,項目組一般通過P/Invoke直接在托管代碼中調用非托管DLL中的函數,提高工作效率,減少維護這部分功能的人力和時間成本。

在設計.Net時,.Net團隊發現現有的Win32 API經過多年完善,規模實在過于龐大,導致.Net沒有為所有的Win32 API編寫基于.Net的托管實現文檔。而通過P/Invoke,則可以方便地使用較為完善的Win32 API函數。

由于機制原因,托管代碼需要通過CLR間接訪問內存,因此,它的運行效率比非托管代碼稍低。在某些對效率要求較高的項目中,程序員通過C或C++編寫核心算法,并封裝成庫。在非托管代碼中,程序員可以通過P/Invoke直接調用,提升軟件的整體效率。

在托管代碼中,需要通過調用函數,來執行非托管代碼。這一過程主要有以下步驟:

(1)獲得需要調用的非托管函數的信息,包括函數名、形參、返回值等內容;

(2)在托管代碼中,聲明對應的非托管函數,并通過DLLImport特性,設置P/Invoke過程中所需要的屬性,主要為非托管庫的名稱、形參和返回值的內存布局方式;

(3)在托管代碼中,直接調用聲明之后的非托管函數。

實際執行過程中,P/Invoke做了以下工作:

(1)查找包含對應函數的DLL;

(2)將對應的DLL裝載到內存中;

(3)查找函數在內存中的地址,并將其參數推入堆棧,以便封送非托管函數所需的數據;

(4)將控制權轉移給非托管函數,確認調用完成,非托管函數返回。

CLR第一次調用函數時,會裝載對應的DLL,并查找函數的內存地址。當該函數發生第一次調用之后,CLR會將該函數的內存地址進行緩存,從而可以提高P/Invoke的使用效率。

在應用程序被卸載之前,裝載過的非托管DLL會一直留在內存中。因此,在關閉軟件時,需要釋放非托管DLL申請的內存。

4 .Net下未捕獲的異常處理

隨著計算機技術的發展,軟件的規模日益擴大。在這樣的背景下,.Net技術雖然在各種大型軟件中應用越來越多,但是這些項目中不可避免地會存在許多第三方庫。

在大型項目中,軟件的穩定性是尤為重要的,因此,如何保證這些第三方庫能夠穩定運行,是項目維護人員不得不面對的工作。所幸,.Net平臺有一套完善且強大的異常處理機制。上述異常處理機制在通過.Net直接操作內存的過程中即使產生越界和內存泄漏,也有較為有效的解決措施。因此,大部分通過.Net技術搭建的軟件穩定性是有保證的。

但是,代碼如果沒有通過CLR運行,而是直接通過P/Invoke機制調用C或C++庫操作內存而產生了異常,那么上述.Net框架提供的異常處理機制將無法進行工作,導致應用程序運行出錯,甚至崩潰。

有兩種情況無法通過這種方法捕獲。

(1)垃圾回收時產生的異常。這種異常一般在Finalize函數中被拋出,但是沒有被捕獲處理。除了這種情況,類似內存耗盡時,也會造成系統產生未經處理的異常,導致應用程序崩潰。

(2)主線程無法捕獲的未處理異常。通常會在應用程序的入口中添加try塊、catch塊來處理程序運行時產生的所有異常,但是應用程序在調用外部組件提供的接口函數或者Win32提供的某些API時,在這些組件內部產生了異常,這些異常無法直接被主線程中的try塊、catch塊捕獲。

因為有上述兩種情況,所以try塊、catch塊是無法捕獲所有異常的。由此可見,即使代碼中所有可能出現問題的地方都加上了try塊、catch塊,也無法杜絕未經捕獲的異常導致應用程序崩潰。因此,要提高程序的健壯性和可維護性,使應用程序能夠長時間穩定運行,軟件工程師需要一種用能截獲未經處理異常的機制,來幫助應用程序從異常中恢復,或者記錄有價值的錯誤信息。

在非托管代碼中,異常的處理會經過以下步驟。

(1)調試器處理。異常發生的時候,如果程序正在被調試,那么異常會被交給調試器。調試器收到異常后,判斷該異常是否需要處理。

(2)執行VEH。異常發生時,如果應用程序不在調試過程中,或者調試器此時返回值為0,那么操作系統會將該異常交給VEH處理。VEH是一個鏈表,可以掛接多個VEH的處理過程,在系統調用時,按順序調用鏈表中的多個函數,依次處理異常。

VEH的返回值有三個:1、0、-1。返回1時,表示無效的處理,實際處理同0。返回0時,將把異常交給VEH鏈表中的下一個進行處理。返回-1時,表示異常已處理完成,此時系統會退出異常處理器,在異常指令處繼續往下執行。

(3)執行SEH。當所有VEH執行完成后,異常會被SEH處理。SHE基于線程棧的異常處理機制,僅處理自身線程內部發生的異常。

(4)頂層異常處理。頂層異常處理實際也是通過SEH實現的。在最頂層的SEH中,可以注冊一個頂層異常處理器,它可以處理所有線程拋出的異常。因此,SEH發現無法處理的異常時,會檢查是否注冊了頂層異常處理,如果注冊了,則調用頂層異常處理。

.Net中,提供了Unhandled Exception Event Handler事件,這一事件可以注冊到頂層異常處理中。通過這一事件,可以截獲系統中未捕獲的異常,并進行處理。

Unhandled Exception Event Handler的事件參數Unhandled Exception Event Argse具體有兩個屬性,分別為 Exception Object和 Is Terminating。Is Terminating表示如果異常不處理,是否會終止當前應用程序。Exception Object為截獲異常的對象。當系統捕獲到未經處理的異常時,通過該對象就可以記錄異常在何處被引發。通過這一信息,軟件設計人員可以在操作該對象的地方做出改進,降低異常發生的可能性。此外,依賴這一事件,可以在程序崩潰退出之前,做好數據備份,記錄錯誤日志工作,以便排查問題。

5 抓取Dump加固程序

在頂層異常處理中,可以記錄下程序的Dump文件,保存未處理異常現場,以便后續分析和改進。

在應用程序中掛接Unhandled Exception事件。事件的響應函數中,構建描述Mini Dump信息的結構體Mini Dump Exception Information,然后通過Marshal.Get Exception Pointers函數獲取異常的位置,通過Win32 API的Get Current Thread Id函數獲取當前的非托管線程號。最后,通過Windbg的Dbghelp.dll中提供的Mini Dump Write Dump函數,將當前應用程序的信息寫入對應的文件中,形成一個Dump文件。

在程序發生異常崩潰時,通過Dump文件,可以分析程序崩潰時的CallStack。配合應用程序對應的Pdb文件和源碼,可以在程序崩潰后繼續調試當前異常。

猜你喜歡
程序機制
構建“不敢腐、不能腐、不想腐”機制的思考
試論我國未決羈押程序的立法完善
人大建設(2019年12期)2019-05-21 02:55:44
自制力是一種很好的篩選機制
文苑(2018年21期)2018-11-09 01:23:06
失能的信仰——走向衰亡的民事訴訟程序
“程序猿”的生活什么樣
英國與歐盟正式啟動“離婚”程序程序
環球時報(2017-03-30)2017-03-30 06:44:45
定向培養 還需完善安置機制
中國衛生(2016年9期)2016-11-12 13:28:08
創衛暗訪程序有待改進
中國衛生(2015年3期)2015-11-19 02:53:32
破除舊機制要分步推進
中國衛生(2015年9期)2015-11-10 03:11:12
注重機制的相互配合
中國衛生(2014年3期)2014-11-12 13:18:12
主站蜘蛛池模板: 97视频在线精品国自产拍| 91美女视频在线观看| 国产尤物视频在线| 国内精品视频在线| 中文国产成人精品久久| 午夜影院a级片| 在线五月婷婷| 欧美a网站| 九九线精品视频在线观看| 欧美成人在线免费| 国产96在线 | 亚洲av成人无码网站在线观看| 99re在线免费视频| 一区二区在线视频免费观看| 久久婷婷色综合老司机| 国产亚洲精品资源在线26u| 欧美精品1区| 一级毛片免费高清视频| AV网站中文| 91原创视频在线| 国产九九精品视频| 中文字幕在线日韩91| 亚瑟天堂久久一区二区影院| 国产精品伦视频观看免费| 欧美一区二区精品久久久| 亚欧美国产综合| 99re在线免费视频| 免费毛片网站在线观看| 亚洲无码一区在线观看| 欧美日韩亚洲国产主播第一区| 国产精品视频久| 中文字幕无码av专区久久| 欧美在线黄| 久久国产精品麻豆系列| 国产靠逼视频| 久久国产av麻豆| 免费毛片a| 99国产精品免费观看视频| 亚洲AⅤ无码国产精品| 欧美国产日韩另类| 国产在线一区视频| 国产在线自揄拍揄视频网站| 欧美精品综合视频一区二区| 国产正在播放| 国产在线97| 欧美区一区二区三| 久久国产亚洲偷自| 2021天堂在线亚洲精品专区| 九九九久久国产精品| 中文字幕在线播放不卡| 91av成人日本不卡三区| 亚洲精品第一页不卡| 亚洲精品在线观看91| 亚洲男人在线天堂| 亚洲 欧美 日韩综合一区| 大乳丰满人妻中文字幕日本| 久草网视频在线| 成年免费在线观看| 亚洲欧美在线看片AI| 成人午夜久久| 国产97视频在线| 亚洲成人高清无码| 人妻精品久久无码区| 欧美日韩中文国产va另类| 国产精品综合久久久| 免费亚洲成人| 在线观看欧美国产| 久久综合色88| 日本成人在线不卡视频| 亚洲欧美人成人让影院| 亚洲天堂日韩av电影| 亚洲毛片在线看| 啊嗯不日本网站| 成人国产精品2021| 欧美精品影院| 亚洲伦理一区二区| 亚洲日韩精品伊甸| 午夜激情婷婷| 成人在线不卡视频| 91久久国产综合精品| 国产精品久久久久久搜索| 91在线国内在线播放老师|