亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        .Net應(yīng)用異常處理研究

        2018-02-19 18:27:15葉信子
        機(jī)械制造 2018年12期
        關(guān)鍵詞:程序機(jī)制

        □ 葉信子

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

        1 .Net異常處理機(jī)制

        人們總是希望編寫出優(yōu)秀的代碼,以便在生產(chǎn)環(huán)境中穩(wěn)定而持久的運(yùn)行。然而,不同的客戶所處的環(huán)境各不相同,很難保證代碼一直正確運(yùn)行。因此,工程項(xiàng)目中,代碼的編寫需要更加注重穩(wěn)定性、容錯性和擴(kuò)展性。

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

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

        2 代碼塊介紹

        2.1 try塊

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

        2.2 catch塊

        catch塊僅在對應(yīng)的try塊拋出異常后才會執(zhí)行。若未發(fā)生任何異常,系統(tǒng)會跳過所有catch塊中的內(nèi)容,繼續(xù)向下執(zhí)行。

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

        2.3 finally塊

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

        總體而言,這三個代碼塊是.Net提供的異常處理機(jī)制的基礎(chǔ)。在try塊中嘗試執(zhí)行一些代碼。如果發(fā)生了錯誤,那么需要在catch塊中進(jìn)行處理,以便從錯誤中恢復(fù)并繼續(xù)執(zhí)行。或者通過catch塊進(jìn)行補(bǔ)償,來撤銷一些狀態(tài)更改,并向調(diào)用者上報錯誤。最終,通過finally塊確保清理操作無論如何都能執(zhí)行。

        3 在.Net中執(zhí)行非托管代碼

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

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

        在設(shè)計.Net時,.Net團(tuán)隊發(fā)現(xiàn)現(xiàn)有的Win32 API經(jīng)過多年完善,規(guī)模實(shí)在過于龐大,導(dǎo)致.Net沒有為所有的Win32 API編寫基于.Net的托管實(shí)現(xiàn)文檔。而通過P/Invoke,則可以方便地使用較為完善的Win32 API函數(shù)。

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

        在托管代碼中,需要通過調(diào)用函數(shù),來執(zhí)行非托管代碼。這一過程主要有以下步驟:

        (1)獲得需要調(diào)用的非托管函數(shù)的信息,包括函數(shù)名、形參、返回值等內(nèi)容;

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

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

        實(shí)際執(zhí)行過程中,P/Invoke做了以下工作:

        (1)查找包含對應(yīng)函數(shù)的DLL;

        (2)將對應(yīng)的DLL裝載到內(nèi)存中;

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

        (4)將控制權(quán)轉(zhuǎn)移給非托管函數(shù),確認(rèn)調(diào)用完成,非托管函數(shù)返回。

        CLR第一次調(diào)用函數(shù)時,會裝載對應(yīng)的DLL,并查找函數(shù)的內(nèi)存地址。當(dāng)該函數(shù)發(fā)生第一次調(diào)用之后,CLR會將該函數(shù)的內(nèi)存地址進(jìn)行緩存,從而可以提高P/Invoke的使用效率。

        在應(yīng)用程序被卸載之前,裝載過的非托管DLL會一直留在內(nèi)存中。因此,在關(guān)閉軟件時,需要釋放非托管DLL申請的內(nèi)存。

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

        隨著計算機(jī)技術(shù)的發(fā)展,軟件的規(guī)模日益擴(kuò)大。在這樣的背景下,.Net技術(shù)雖然在各種大型軟件中應(yīng)用越來越多,但是這些項(xiàng)目中不可避免地會存在許多第三方庫。

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

        但是,代碼如果沒有通過CLR運(yùn)行,而是直接通過P/Invoke機(jī)制調(diào)用C或C++庫操作內(nèi)存而產(chǎn)生了異常,那么上述.Net框架提供的異常處理機(jī)制將無法進(jìn)行工作,導(dǎo)致應(yīng)用程序運(yùn)行出錯,甚至崩潰。

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

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

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

        因?yàn)橛猩鲜鰞煞N情況,所以try塊、catch塊是無法捕獲所有異常的。由此可見,即使代碼中所有可能出現(xiàn)問題的地方都加上了try塊、catch塊,也無法杜絕未經(jīng)捕獲的異常導(dǎo)致應(yīng)用程序崩潰。因此,要提高程序的健壯性和可維護(hù)性,使應(yīng)用程序能夠長時間穩(wěn)定運(yùn)行,軟件工程師需要一種用能截獲未經(jīng)處理異常的機(jī)制,來幫助應(yīng)用程序從異常中恢復(fù),或者記錄有價值的錯誤信息。

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

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

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

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

        (3)執(zhí)行SEH。當(dāng)所有VEH執(zhí)行完成后,異常會被SEH處理。SHE基于線程棧的異常處理機(jī)制,僅處理自身線程內(nèi)部發(fā)生的異常。

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

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

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

        5 抓取Dump加固程序

        在頂層異常處理中,可以記錄下程序的Dump文件,保存未處理異?,F(xiàn)場,以便后續(xù)分析和改進(jìn)。

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

        在程序發(fā)生異常崩潰時,通過Dump文件,可以分析程序崩潰時的CallStack。配合應(yīng)用程序?qū)?yīng)的Pdb文件和源碼,可以在程序崩潰后繼續(xù)調(diào)試當(dāng)前異常。

        猜你喜歡
        程序機(jī)制
        構(gòu)建“不敢腐、不能腐、不想腐”機(jī)制的思考
        試論我國未決羈押程序的立法完善
        自制力是一種很好的篩選機(jī)制
        文苑(2018年21期)2018-11-09 01:23:06
        失能的信仰——走向衰亡的民事訴訟程序
        “程序猿”的生活什么樣
        英國與歐盟正式啟動“離婚”程序程序
        定向培養(yǎng) 還需完善安置機(jī)制
        創(chuàng)衛(wèi)暗訪程序有待改進(jìn)
        破除舊機(jī)制要分步推進(jìn)
        注重機(jī)制的相互配合
        成在线人视频免费视频| 久久成人影院精品777| 亚洲熟女乱色一区二区三区| 久久国产品野战| 国产av在线观看91| 麻豆精品国产av在线网址| 欧美最大胆的西西人体44| 一国产区在线观看| 精品国产乱码久久免费看| 91精品国产福利在线观看麻豆| 亚洲国产精品成人一区二区在线| 日本视频二区在线观看| 又长又大又粗又硬3p免费视频| 国产香蕉尹人综合在线观| 精品亚洲乱码一区二区三区| 久久国产黄色片太色帅| 激性欧美激情在线| 成人性做爰aaa片免费看| 国产在线不卡免费播放| 日本一区二区在线播放| 亚洲av成人片色在线观看 | 亚洲九九夜夜| 亚洲精品中文字幕乱码| 无码人妻一区二区三区兔费| 天天做天天爱天天综合网| 免费国人成人自拍视频| 亚洲国产av一区二区三区精品| 国产精品亚洲欧美大片在线看 | 国产精品27页| 国产一区二区不卡av| 国产精品久久久久9999| 精品国产黑色丝袜高跟鞋| 久久麻豆精亚洲av品国产精品| 国产91久久精品成人看网站| 免费人成小说在线观看网站 | 欧美老妇牲交videos| 天躁夜夜躁狼狠躁| 亚洲日本无码一区二区在线观看 | 射精区-区区三区| 国模丽丽啪啪一区二区| 亚洲AV秘 无码一区二p区三区|