1. 程式人生 > >.NET Framework 4.5 的五大特性

.NET Framework 4.5 的五大特性

http://www.itstrike.cn/Question/10777f22-b683-45ee-a957-c38368823a01.html
介紹
從.NET4.5釋出到現在已經有一年多了。但問題是針對最近微軟釋出的版本資訊中,大部分的.NET開發人員所討論交流的只是其中的一兩個特性。其他的特性僅僅停留在MSDN中或者淪為簡介文件。
例如:現在問一個.NET開發人員:.NET4.5的核心框架是什麼?他們大多數將只能說出非同步和等待(至少,我接觸的人中,只談論過這些特性)
再次,瀏覽所有特性確實是一件非常困難的事情。因為,從你所從事的方面來看,有些特性聽起來不是那麼讓你感興趣。
因此,在這篇文章中,我挑選了.NET 4.5中介紹的五個我喜歡的特性。再次宣告:不排除在我所喜歡的特性中,你一個都不感興趣。但是寫這篇文章之前,我時刻謹記更大.NET社群中提到的特性,並且我希望可以滿足你的預期。

注意:這篇文章僅涉及核心特性,ASP.NET,WCF,WPF,WWF等等不在討論範圍之內。

特性1:非同步和等待(程式碼標記)
這個特性已經快被討論濫了,而且幾乎每一個.NET技術狂人都會談論此特性。但是此特性依舊是我的最愛。稍後您將明白為什麼我會以這些話作為開場白。

非同步(async)和等待(await )是用來標記程式碼在一個任務(執行緒)完成後,需要繼續執行程式碼的所在位置的標記量。
讓我們通過理解下面的程式碼來儘量理解上面的描述。如果你明白下面的程式碼流程:

在靜態無返回值的主函式Static void main()入口處呼叫Method()函式。

Method()方法生成一個延時10秒的任務(執行緒)LongTask。

同時,任務被呼叫結束,程式執行到返回 Method()函式執行剩餘程式碼。也就是說:呼叫是多執行緒的,等待10秒的任務LongTask 和 Method()方法中剩餘程式碼同時在執行。

現在,在上述情況下,若我們想要以另一種方式實現第三步的操作。那麼非同步和等待這兩個關鍵字可以幫助我們。

現在,關於非同步和等待有三點需要重點注意:

非同步和等待是一對關鍵字,你不能單獨使用。

非同步在一個方法中做標記,這個關鍵字只是一個用來標記這個方法有等待(await)關鍵字的指示器。

這個等待關鍵字標記了任務重新開始的位置。所以,你要在task這個執行緒中始終尋找等待(await)這個關鍵字。

下面是前面應用了非同步(async)和等待(await)的程式碼一個修改後的版本。所有步驟都保留不變,除了第三步是完成第二步之後才執行。 簡而言之,就是程式完成任務(執行緒)的操作後,回到Method()方法,繼續執行。

現在你讀完了“非同步”和“等待”的討論。讓我們一起討論一個問題:上述程式碼的行為,也可以用Task.Wait或者 Task.ContinueWith 來實現。那麼它們有什麼區別?我把這個問題留作家庭作業,請自行完成。

特性2:Zip 附屬功能(Zip壓縮)

Zip是一個被廣泛接受的檔案檔案格式之一。Zip壓縮格式以*.Zip固定格式為大多數的作業系統所支援。

在Windows作業系統中,被稱作“壓縮檔案”.

在MAC OS(蘋果專用系統)中則被稱為“檔案公用程式”

現在,在.NET中我們還沒有嵌入對Zip解壓程式的支援。很多開發人員第三方元件如:DotnetZip。在.NET4.5當中Zip特性已經融入了framework當中,且名稱空間為:System.IO.Compression.

第一步,你需要參考兩個名稱空間:

System.IO.Compression.FileSystem

System.IO.Compression

下一步是:引入下面兩個名稱空間:

1
using System.IO.Compression;
如果你想要將一個檔案壓縮為Zip格式檔案,你可以用如下所示的CreateFromDirectory方法。

1
ZipFile.CreateFromDirectory(@”D:\data”,@”D:\data.zip”);
特性3:正則表示式超時

“Regex”在資料驗證方面最受歡迎。考慮到您可能對“Regex”完全陌生的。請參考我介紹Regex如何運作的視訊。But because of the typical parsing logic of regex it is exposed to DOS attacks. Let us try to understand in detail what I mean by that.但是由於正則表示式典型的邏輯解析是暴露在DOS攻擊之下的。讓我們嘗試瞭解一下細節來明白我為什麼這麼說。
例如,我們來看一下這個規則表示式-“^(\d+)$”。這個正則表示式的規則是隻有數字符合條件。你也可以看一看下面描述正則表示式如何評估輸入資訊的符號圖。現在,假設我們想要驗證“123456x”。正如下圖所示,正則表示式將走六條路徑。

但是如果我們再擴充套件一位輸入引數,它將有七條路徑。也就是說,隨著輸入引數長度的增加,正則表示式的驗證需要更多地時間來驗證。即:驗證所需時間和輸入引數的長度為線型關係。

現在讓我們把前面的表示式“^(\d+) (\d+)+ ”。如果你意識到了這個正則表示式寫的非常複雜。而且我們想驗證“123456x”。它將執行32條路徑。 如果你再新增一個字元,它遍歷的路徑將變成64條。

也就是說,對上述正則表示式而言,驗證輸入引數的長度與消耗時間是指數關係。

現在,你可能會問:這些有關係嗎?但是我要說的是:當正則表示式執行線性相關的驗證時,這個特點可能被黑客利用,以實現DOS攻擊。他們可以輸入非常長的字串,使你的應用永遠處於掛起狀態(始終處於正則驗證狀態)。
一個比較合適的解決方法是:設定正則操作的超時限制。好訊息是,在.NET4.5中,你可以像下面所示程式碼那樣,為正則驗證新增一個超時屬性。所以,如果你收到任何型別的惡意注入時,你的應用不會陷入死迴圈。

1
2
3
4
5
6
7
8
9
try
{
var regEx = new Regex(@”^(\d+)+$”, RegexOptions.Singleline, TimeSpan.FromSeconds(2));
var match = regEx.Match(“123453109839109283090492309480329489812093809x”);
}
catch (RegexMatchTimeoutException ex)
{
Console.WriteLine(“Regex Timeout”);
}

特性4:配置檔案的優化(提升啟動時效能)

眾所周知,.NET程式碼處於半編譯格式。在執行時,JIT編譯器才會執行和解釋半編譯的IL程式碼為本機的機器碼。由於第一次執行.NET程式的時候JIT忙於把IL編碼解釋為機器程式碼,因此程式執行的會非常慢。這也是JIT被很多.NET程式設計師詬病的一個問題。
為了縮減啟動時間,在.NET4.5中。我們有了一個叫做“配置檔案優化”的一個利器。檔案中只包含了程式啟動時所需方法的列表。所以,當程式啟動時,後臺的JIT將會把這些方法翻譯成機器語言/本地編碼並執行。
後臺執行的JIT將跳過多數控制器,直接編譯啟動項配置檔案裡的方法,因此可以大大縮減所需時間。需要注意的是:你需要多核硬體的支援,否則的話,可以直接忽略此特性了。

為了建立“配置檔案”這個檔案,你首先需要引入System.Runtime這個名稱空間。第二步,你要呼叫靜態類ProfileOptimization 中的SetProfileRoot和StartProfile 方法。現在,當程式啟動後臺JIT時,它將通過後臺讀取配置檔案並編譯啟動方法來縮短啟動時間。

1
2
3
4
5
6
using System.Runtime;

// Call the Setprofilerroot and Startprofile method
ProfileOptimization.SetProfileRoot(@”D:\ProfileFile”);

ProfileOptimization.StartProfile(“ProfileFile”);
注意:ASP.NET 4.5和Silverlight的應用程式預設採用Profileoptimization 靜態類進行處理。因此上述程式碼不必再此類專案中再寫一遍。

特性5:垃圾回收器(GC後臺清理)

垃圾回收器在一個.NET程式中是一項非常繁重的任務。並且,在ASP.NET應用程式中表現更為明顯。ASP.NET的應用程式在伺服器端執行,而且許多客戶端會向伺服器傳送請求來建立物件。這使得GC清理非必要物件的工作更加繁重。

在.NET4.0中,當GC清理垃圾時,所有應用程式的執行緒是被中止的。你可以在上圖中看到,我們有三個應用程式的執行緒正在執行,我們有兩個GC分別執行在不同的執行緒。一個GC執行緒對應一個本地程序。現在,應用程式的執行緒正在正常執行。現在,隨著這些程式的執行緒執行它們任務的過程中,它們也建立了託管物件。
在某些事件節點上,後臺的GC執行並開始清理。當這些後臺的GC開始清理時,它們將中止所有應用程式的執行緒,這將導致在此時間節點上伺服器和應用程式間的響應時間將會拉長。

為了解決以上問題,伺服器端的GC應運而生。伺服器GC會多開啟一個後臺執行的執行緒。這個執行緒將在後臺執行,並且持續清理二代物件。因此,減少了主GC執行緒的負載。由於GC採用雙執行緒執行,主程式的執行緒被中止的頻率將大大境地。從而提高了應用程式的執行效率。為了使用伺服器GC,我們需要在配置檔案中將新增gcServer XML標籤,並使之有效。如下所示

1
2
3
4
5