深入.NET Framework 4.0 關于Lazy的點滴
在微軟發布的.NET Framework 4.0的Beta 2版本中,其又給我們帶來了很多新東西,由于不知道正式版與之前的版本是否有過改進,我們只在這里來單純地談談在.NET Framework 4.0中關于Lazy<T>的實現。
1.Lazy<T>概述
我們也許會遇到這樣一種情況,我們有一個大家伙(大對象)需要創建,那么這個對象的創建時需要較長的時間,同時也需要在托管堆上分配較多的空間。那么在.NET Framework 4.0中提供了這樣一個很聰明的方式:Lazy<T>(我們可以稱之為懶對象)。當然,在之前,很多人也曾對其進行過自己的實現,那么我們在這里就可以把Lazy<T>的作用總結為一句話:按需延遲加載。
2.Lazy<T>的使用
了解了Lazy<T>的作用,讓我們就來看下Lazy<T>如何應用:
- classProgram
- {
- staticvoidMain(string[]args)
- {
- Lazy<Large>lazyObject=newLazy<Large>();
- Console.WriteLine(lazyObject.IsValueCreated);
- lazyObject.Value.Test();
- Console.WriteLine(lazyObject.IsValueCreated);
- }
- }
- [Serializable]
- classLarge
- {
- publicLarge(){}
- publicvoidTest()
- {
- Console.WriteLine("Test");
- }
- }
這個例子很簡單,也是Lazy<T>最基本,也是最常用的應用方式。
3.實現自己的Lazy<T>
在.NET Framework 4.0之前,大對象就是存在的,那么對于一個大型系統而言,怎么樣對付一個大對象呢。在我看來有兩點:延遲加載和即時清理。前者解決創建問題,后者解決回收問題,那么在來看Lazy<T>的.NET Framework實現之前,我們先來自己實現一個簡單的Lazy<T>吧。
- classMyLazy<T>whereT:new()
- {
- privateTvalue;
- privateboolisLoaded;
- publicMyLazy()
- {
- isLoaded=false;
- }
- publicTValue
- {
- get
- {
- if(!isLoaded)
- {
- value=newT();
- isLoaded=true;
- }
- returnvalue;
- }
- }
- }
這應該是最簡單版本的Lazy<T>了,沒有線程安全檢測,其實什么都沒有,只有著訪問時創建真實對象,可是對于我們一般的應用來說也許就已經足夠了。 #p#
4.Lazy<T>的.NET Framework實現
原本還想解釋下代碼的,可是太多了,就寫些主要吧,其實.NET Framework和上面的實現大同小異,有兩點主要的不同:
A.引入了Boxed內部類:
- [Serializable]
- privateclassBoxed
- {
- //Fields
- internalTm_value;
- //Methods
- [TargetedPatchingOptOut("PerformancecriticaltoinlinethistypeofmethodacrossNGenimageboundaries")]
- internalBoxed(Tvalue)
- {
- this.m_value=value;
- }
- }
該內部類取代了我在上面實現中的泛型約束,使之更通用,但是我們也應該注意到,如果T為結構體,那么由于T很大,所以裝箱拆箱反而也許是個更耗費效率的事情,因此,個人建議,對值類型慎用Lazy<T>。
B.線程安全的控制
在線程安全的控制選項中,.NET Framework為我們提供了這樣的枚舉選項:
- publicenumLazyThreadSafetyMode
- {
- None,
- PublicationOnly,
- ExecutionAndPublication
- }
不做多余解釋,關于這三者的具體意思,MSDN中已經說的很清楚了,可參加這里,里面的代碼比較麻煩,就不多說了。
5.完善的大對象解決方案
在Anytao文章的回復中提到了一點是:Lazy+WeakReference才是實現一個大對象的完整解決之道,一個按需加載,一個不定清理,加到一起才完美。
本文轉自飛林沙的博客,
原文地址:http://www.cnblogs.com/kym/archive/2010/02/21/1670226.html
【編輯推薦】