.NET 2.0 CER学习笔记
生活随笔
收集整理的這篇文章主要介紹了
.NET 2.0 CER学习笔记
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
CER是.NET 2.0 CLR方面的重要改進(jìn),旨在幫助那些對(duì)穩(wěn)定性高度苛刻的程序?qū)Ω?NET Framework的不穩(wěn)定因素。因?yàn)槠胀ǖ某绦蚝苌贂?huì)用到,所以一直沒有對(duì)這個(gè)特性加以足夠重視?,F(xiàn)在碰巧在翻譯書籍的過程中用到,就一起來學(xué)習(xí)一下。
首先,需要提到異步異常的問題。異步異常就是指OutOfMemoryException、StackOverflowException和ThreadAbortException等系統(tǒng)異常。說他們“異步”是因?yàn)樗麄兛梢栽诰€程代碼執(zhí)行到任何地方的時(shí)候發(fā)生。一般的異常,比如FileNotFoundException是由代碼自己產(chǎn)生的,因此可以用Try語句正常捕捉和處理。而異步異常則是CLR產(chǎn)生的。而且,這些異常都預(yù)示著非常嚴(yán)重的錯(cuò)誤,代碼自己通常都會(huì)手足無措。比方說內(nèi)存耗盡了,代碼自己即使Catch了也無濟(jì)于事,都不知道剛剛哪一步出的問題,也不知道該怎么繼續(xù)執(zhí)行。ThreadAbortException通常是由Thread.Abort方法引發(fā),如果要Abort的線程正在進(jìn)行很關(guān)鍵的人物,比如修改一個(gè)全局對(duì)象的狀態(tài),那么發(fā)生ThreadAbortException可能會(huì)讓整個(gè)程序的狀態(tài)受損,進(jìn)而產(chǎn)生錯(cuò)誤的行為。因此,需要有種機(jī)制告訴CLR,我們要進(jìn)行的事情很關(guān)鍵,不容打斷,這就是CER——Constrained Execution Region。
聲明CER很簡單,先調(diào)用System.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions()方法,再緊接一個(gè)Try...Catch...Finally塊即可。注意,這個(gè)Try必須緊接著PrepareConstrainedRegions()方法,而且,只有Catch和Finally塊的內(nèi)容成為CER。如下所示
RuntimeHelpers.PrepareConstrainedRegions()
Try
Catch
????'注意,這里是CER
Finally
????'這里也是CER
End?Try 一般情況下都用Finally塊來做CER。CER與普通代碼不同,在CER執(zhí)行期間CLR不能發(fā)出異步異常。因此CLR就必須采取一些措施。首先CER會(huì)將ThreadAbortException推遲到CER結(jié)束之后才發(fā)生,這比較容易做到。第二,為了避免OutOfMemoryException,CLR會(huì)將CER中用到的所有方法(注意,這里是從代碼靜態(tài)觀察,而不是實(shí)際調(diào)用的方法)以及這些方法所調(diào)用到的所有方法全都編譯成本地代碼,然后根據(jù)情況預(yù)測可能的內(nèi)存不足并提前到CER之前引發(fā)。然而,這個(gè)方法并不能對(duì)付堆棧益處錯(cuò)誤,所以這個(gè)方法會(huì)事先保留48K的??臻g以防萬一。然而根據(jù)MSDN文檔,StackOverflowException還是可能會(huì)發(fā)生的。
為了確保CER這種原理能夠工作,首先CER之內(nèi)不能在堆上進(jìn)行任何分配操作,包括后臺(tái)進(jìn)行的分配操作。除了不能用New分配引用類型的對(duì)象之外,也不能進(jìn)行裝箱、線程同步鎖操作或者訪問多維數(shù)組。
剛才介紹到,CLR會(huì)事先編譯CER中所有用到的方法以及它們各自調(diào)用的所有方法。那么聰明的人一定能看出一個(gè)問題,那就是通過委托和虛函數(shù)機(jī)制調(diào)用的方法無法事先準(zhǔn)確判斷,因而就無從準(zhǔn)備。因此,RuntimeHelpers還提供了兩個(gè)方法——PrepareMethod和PrepareDelegate。調(diào)用之前務(wù)必用這兩個(gè)方法準(zhǔn)備所有虛函數(shù)的實(shí)際版本和委托變量。使用CER是需要極其小心準(zhǔn)備的,因此不是隨隨便便使用的特性。RuntimeHelpers還有許多其它方法對(duì)應(yīng)各種有變數(shù)的情況??傊?#xff0c;CER的宗旨就是在執(zhí)行之前將所有可以知道的情況盡數(shù)分析透徹以便提前判斷CER中的操作到底有沒有可能順利完成。
下面用ThreadAbortException來做一個(gè)試驗(yàn),因?yàn)檫@個(gè)異常是最容易引發(fā)的:
Imports?System.Runtime.CompilerServices
Imports?System.Threading
Module?Module1Module?Module1
????Dim?globalArray()?As?Integer
????Sub?Main()Sub?Main()
????????globalArray?=?New?Integer(50000000)?{}
????????Dim?t?As?New?Thread(AddressOf?Thread1)
????????t.Start()
????????t.Abort()
????????t.Join()
????????Console.WriteLine(AllEquals(globalArray,?100))
????End?Sub
????Function?AllEquals()Function?AllEquals(Of?T)(ByVal?arr()?As?T,?ByVal?value?As?T)?As?Boolean
????????For?i?As?Integer?=?0?To?arr.Length?-?1
????????????If?Not?arr(i).Equals(value)?Then?Return?False
????????Next
????????Return?True
????End?Function
????Sub?Thread1()Sub?Thread1()
????????RuntimeHelpers.PrepareConstrainedRegions()
????????Try
????????Finally
????????????For?i?As?Integer?=?0?To?50000000
????????????????globalArray(i)?=?100
????????????Next
????????End?Try
????End?Sub
End?Module ?先把準(zhǔn)備CER的代碼注釋掉,可以發(fā)現(xiàn)這個(gè)方法不是總能執(zhí)行成功的,ThreadAbortException可能會(huì)將數(shù)組的操作打斷,以至于留下不正常的狀態(tài)。如果在你的計(jì)算機(jī)上該方法不會(huì)失敗,可以嘗試改變數(shù)組的大小。接下來應(yīng)用CER,會(huì)發(fā)現(xiàn)出現(xiàn)異常時(shí)程序執(zhí)行的速度劇烈下降,但是最終方法總能夠成功地完成。這就是CER所帶來的好處。
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀
首先,需要提到異步異常的問題。異步異常就是指OutOfMemoryException、StackOverflowException和ThreadAbortException等系統(tǒng)異常。說他們“異步”是因?yàn)樗麄兛梢栽诰€程代碼執(zhí)行到任何地方的時(shí)候發(fā)生。一般的異常,比如FileNotFoundException是由代碼自己產(chǎn)生的,因此可以用Try語句正常捕捉和處理。而異步異常則是CLR產(chǎn)生的。而且,這些異常都預(yù)示著非常嚴(yán)重的錯(cuò)誤,代碼自己通常都會(huì)手足無措。比方說內(nèi)存耗盡了,代碼自己即使Catch了也無濟(jì)于事,都不知道剛剛哪一步出的問題,也不知道該怎么繼續(xù)執(zhí)行。ThreadAbortException通常是由Thread.Abort方法引發(fā),如果要Abort的線程正在進(jìn)行很關(guān)鍵的人物,比如修改一個(gè)全局對(duì)象的狀態(tài),那么發(fā)生ThreadAbortException可能會(huì)讓整個(gè)程序的狀態(tài)受損,進(jìn)而產(chǎn)生錯(cuò)誤的行為。因此,需要有種機(jī)制告訴CLR,我們要進(jìn)行的事情很關(guān)鍵,不容打斷,這就是CER——Constrained Execution Region。
聲明CER很簡單,先調(diào)用System.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions()方法,再緊接一個(gè)Try...Catch...Finally塊即可。注意,這個(gè)Try必須緊接著PrepareConstrainedRegions()方法,而且,只有Catch和Finally塊的內(nèi)容成為CER。如下所示
RuntimeHelpers.PrepareConstrainedRegions()
Try
Catch
????'注意,這里是CER
Finally
????'這里也是CER
End?Try 一般情況下都用Finally塊來做CER。CER與普通代碼不同,在CER執(zhí)行期間CLR不能發(fā)出異步異常。因此CLR就必須采取一些措施。首先CER會(huì)將ThreadAbortException推遲到CER結(jié)束之后才發(fā)生,這比較容易做到。第二,為了避免OutOfMemoryException,CLR會(huì)將CER中用到的所有方法(注意,這里是從代碼靜態(tài)觀察,而不是實(shí)際調(diào)用的方法)以及這些方法所調(diào)用到的所有方法全都編譯成本地代碼,然后根據(jù)情況預(yù)測可能的內(nèi)存不足并提前到CER之前引發(fā)。然而,這個(gè)方法并不能對(duì)付堆棧益處錯(cuò)誤,所以這個(gè)方法會(huì)事先保留48K的??臻g以防萬一。然而根據(jù)MSDN文檔,StackOverflowException還是可能會(huì)發(fā)生的。
為了確保CER這種原理能夠工作,首先CER之內(nèi)不能在堆上進(jìn)行任何分配操作,包括后臺(tái)進(jìn)行的分配操作。除了不能用New分配引用類型的對(duì)象之外,也不能進(jìn)行裝箱、線程同步鎖操作或者訪問多維數(shù)組。
剛才介紹到,CLR會(huì)事先編譯CER中所有用到的方法以及它們各自調(diào)用的所有方法。那么聰明的人一定能看出一個(gè)問題,那就是通過委托和虛函數(shù)機(jī)制調(diào)用的方法無法事先準(zhǔn)確判斷,因而就無從準(zhǔn)備。因此,RuntimeHelpers還提供了兩個(gè)方法——PrepareMethod和PrepareDelegate。調(diào)用之前務(wù)必用這兩個(gè)方法準(zhǔn)備所有虛函數(shù)的實(shí)際版本和委托變量。使用CER是需要極其小心準(zhǔn)備的,因此不是隨隨便便使用的特性。RuntimeHelpers還有許多其它方法對(duì)應(yīng)各種有變數(shù)的情況??傊?#xff0c;CER的宗旨就是在執(zhí)行之前將所有可以知道的情況盡數(shù)分析透徹以便提前判斷CER中的操作到底有沒有可能順利完成。
下面用ThreadAbortException來做一個(gè)試驗(yàn),因?yàn)檫@個(gè)異常是最容易引發(fā)的:
Imports?System.Runtime.CompilerServices
Imports?System.Threading
Module?Module1Module?Module1
????Dim?globalArray()?As?Integer
????Sub?Main()Sub?Main()
????????globalArray?=?New?Integer(50000000)?{}
????????Dim?t?As?New?Thread(AddressOf?Thread1)
????????t.Start()
????????t.Abort()
????????t.Join()
????????Console.WriteLine(AllEquals(globalArray,?100))
????End?Sub
????Function?AllEquals()Function?AllEquals(Of?T)(ByVal?arr()?As?T,?ByVal?value?As?T)?As?Boolean
????????For?i?As?Integer?=?0?To?arr.Length?-?1
????????????If?Not?arr(i).Equals(value)?Then?Return?False
????????Next
????????Return?True
????End?Function
????Sub?Thread1()Sub?Thread1()
????????RuntimeHelpers.PrepareConstrainedRegions()
????????Try
????????Finally
????????????For?i?As?Integer?=?0?To?50000000
????????????????globalArray(i)?=?100
????????????Next
????????End?Try
????End?Sub
End?Module ?先把準(zhǔn)備CER的代碼注釋掉,可以發(fā)現(xiàn)這個(gè)方法不是總能執(zhí)行成功的,ThreadAbortException可能會(huì)將數(shù)組的操作打斷,以至于留下不正常的狀態(tài)。如果在你的計(jì)算機(jī)上該方法不會(huì)失敗,可以嘗試改變數(shù)組的大小。接下來應(yīng)用CER,會(huì)發(fā)現(xiàn)出現(xiàn)異常時(shí)程序執(zhí)行的速度劇烈下降,但是最終方法總能夠成功地完成。這就是CER所帶來的好處。
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀
總結(jié)
以上是生活随笔為你收集整理的.NET 2.0 CER学习笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 听webcast的行为型模式篇-迭代器模
- 下一篇: Oracle 序列的创建和使用