深入Lazy——.NET Framework 4.0

來源:互聯網
上載者:User

.NET Framework 4 在一次次跳票中終於發布了,在一次偶然的機會,我看到了 Anytao 的 [你必須知道的.NET]第三十三回,深入.NET 4.0之,Lazy<T>點滴 。

我沒有看過在.NET Framework 4.0 beta2 的 關於 Lazy<T> 的實現,也不知道正式版與之前的版本是否有過改進(改變),我只在這裡來單純地談在.NET Framework 4 中 Lazy<T> 的實現。

1. Lazy<T> 概述

我們也許會遇到這樣一種情況,我們有一個大傢伙(大對象)需要建立,那麼這個對象的建立時需要較長的時間,同時也需要在託管堆上分配較多的空間。

那麼在.NET Framework 4 中提供了這樣一個很聰明的方式:Lazy<T>(我們可以稱之為懶對象)。當然,在之前,很多人也曾對其進行過自己的實現。

那麼我們在這裡就可以把 Lazy<T> 的作用總結為一句話,按需消極式載入

2. Lazy<T> 的使用

瞭解了Lazy<T>的作用,讓我們就來看下Lazy<T>如何應用。

class Program
{
static void Main(string[] args)
{
Lazy<Large> lazyObject = new Lazy<Large>();
Console.WriteLine(lazyObject.IsValueCreated);
lazyObject.Value.Test();
Console.WriteLine(lazyObject.IsValueCreated);
}
}

[Serializable]
class Large
{
public Large() { }
public void Test()
{
Console.WriteLine("Test");
}
}

運行結果如下:

這個例子很簡單,也是Lazy<T>最基本,也是最常執行的 App方式。

3. 實現自己的Lazy<T>

在.NET Framework 4.0之前,大對象就是存在的,那麼對於一個大型系統而言,怎麼樣對付一個大對象呢。在我看來有兩點:消極式載入和即時清理。前者解決建立問題,後者解決回收問題。

那麼在來看Lazy<T>的.NET Framework實現之前,我們先來自己實現一個簡單的Lazy<T>吧。

class MyLazy<T> where T : new()
{
private T value;
private bool isLoaded;
public MyLazy()
{
isLoaded = false;
}
public T Value
{
get
{
if (!isLoaded)
{
value = new T();
isLoaded = true;
}
return value;
}
}
}

這應該是最簡單版本的Lazy<T>了,沒有安全執行緒檢測,其實什麼都沒有,只有著訪問時建立真實對象,可是對於我們一般的應用來說也許就已經足夠了。

4. Lazy<T>的.NET Framework實現

原本還想解釋下代碼的,可是太多了,解釋不動了…….就寫些主要把。

其實.NET Framework和上面的實現大同小異,有兩點主要的不同:

A. 引入了Boxed內部類:

[Serializable]
private class Boxed
{
// Fields
internal T m_value;

// Methods
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
internal Boxed(T value)
{
this.m_value = value;
}
}

該內部類取代了我在上面實現中的泛型約束,使之更通用。

但是我們也應該注意到,如果T為結構體,那麼由於T很大,所以裝箱拆箱反而也許是個更耗費效率的事情,因此,個人建議,對實值型別慎用Lazy<T>。

B. 安全執行緒的控制

線上程安全的控制選項中,.NET Framework為我們提供了這樣的枚舉選項:

public enum LazyThreadSafetyMode
{
None,
PublicationOnly,
ExecutionAndPublication
}

不做多餘解釋,關於這三者的具體意思,MSDN中已經說的很清楚了,可參加 這裡 。

裡面的代碼比較麻煩,就不多說了。

5. 完善的大對象解決方案

在 Anytao 文章的回複中,我就提到了一點是:

個人倒覺得Lazy+WeakReference才是實現一個大對象的完整解決之道,一個按需載入,一個不定清理.....

加到一起才完美。

但是 老趙 說:

又不是所有的大對象都需要自動清理……

那麼我就不再重複去總結了,這兩句話加到一起,我想應該可以得出一個比較完善的大對象處理方案吧。

如果這樣,我們是否能對應地去建立一個單獨的實作類別:WeakLazy<T>呢。

這樣相當於我們有了WeakReference,有了Lazy<T>,還有了WeakLazy<T>,那麼我們是不是就可以很完整地根據情況選擇應用了呢!

6. 總結

原本想寫一些稍微深入點的東西,可是寫到最後,發現仍為皮毛而,歎乎…….

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.