前言 按需載入對象延遲載入實際是推遲進行創建對象,直到對其調用後才進行創建初始化,延遲(懶載入)的好處是提高系統性能,避免不必要的計算以及不必要的資源浪費。 常規有這些情況: 對象創建成本高且程式可能不會使用它。 例如,假定記憶體中有具有 Orders 屬性的 Customer 對象,該對象包含大量 ...
前言
按需載入對象延遲載入實際是推遲進行創建對象,直到對其調用後才進行創建初始化,延遲(懶載入)的好處是提高系統性能,避免不必要的計算以及不必要的資源浪費。
常規有這些情況:
- 對象創建成本高且程式可能不會使用它。 例如,假定記憶體中有具有 Orders 屬性的 Customer 對象,該對象包含大量 Order 對象,初始化這些對象需要資料庫連接。 如果用戶永遠不要求顯示 Orders 或在計算中使用該數據,則無需使用系統記憶體或計算周期來創建它。 通過使用 Lazy
來聲明 Orders對象用於遲緩初始化,可以避免在不使用該對象時浪費系統資源。 - 對象創建成本高,且希望將其創建推遲到其他高成本操作完成後。 例如,假定程式在啟動時載入多個對象實例,但是只需立即載入其中一部分。 可以通過推遲初始化不需要的對象,直到創建所需對象,提升程式的啟動性能。(來源官方)
示例
創建用戶類
public class User
{
public string Name { get; set; }
public int Age { get; set; }
public User() {
this.Name = "Name";
this.Age = 0;
}
}
預設情況下,Lazy
class Program
{
static void Main(string[] args)
{
Lazy<User> user = new Lazy<User>();
ThreadLocal<User> threadLocal = new ThreadLocal<User>();
if (!user.IsValueCreated)
Console.WriteLine("The object is not initialized");
Console.WriteLine(user.Value.Name);
user.Value.Name = "Name1";
user.Value.Age = 1;
Console.WriteLine(user.Value.Name);
Console.Read();
}
}
對象的線程安全性 | LazyThreadSafetyMode mode 參數 | 布爾 isThreadSafe 參數 | 沒有線程安全性參數 |
---|---|---|---|
完全線程安全;一次只有一個線程嘗試初始化值。 | ExecutionAndPublication | true | 可以。 |
非線程安全。 | None | false | 不適用。 |
完全線程安全;線程爭用以初始化值。 | PublicationOnly | 不適用。 | 不適用。 |
其中IsValueCreated屬性是個Boolean類型,我們可以通過此屬性去確定當前對象有沒有被初始化
調用後,進行了創建操作
再說說Lazy中幾個構造函數,
public Lazy (bool isThreadSafe):
isThreadSafe 的布爾參數,該方法參數用於指定是否從多線程訪問 Value 屬性。 如果想要僅從一個線程訪問屬性,則傳入 false 以獲取適度的性能優勢。 如果想要從多線程訪問屬性,則傳入 true 以指示 Lazy實例正確處理爭用條件(初始化時一個線程引發異常)。 public Lazy (LazyThreadSafetyMode mode):提供線程安全模式。
public Lazy (Func
valueFactory) :
lambda 表達式傳遞給新的 Lazy對象的構造函數。 下一次訪問 Value 屬性將導致新 Lazy 的初始化,並且其 Value 屬性此後會返回已分配給該屬性的新值。
總結
參考:https://docs.microsoft.com/en-us/dotnet/framework/performance/lazy-initialization