詳解C# Lazy Loading(延遲加載)
前言
按需加載對(duì)象延遲加載實(shí)際是推遲進(jìn)行創(chuàng)建對(duì)象,直到對(duì)其調(diào)用后才進(jìn)行創(chuàng)建初始化,延遲(懶加載)的好處是提高系統(tǒng)性能,避免不必要的計(jì)算以及不必要的資源浪費(fèi)。
常規(guī)有這些情況:
- 對(duì)象創(chuàng)建成本高且程序可能不會(huì)使用它。 例如,假定內(nèi)存中有具有 Orders 屬性的 Customer 對(duì)象,該對(duì)象包含大量 Order 對(duì)象,初始化這些對(duì)象需要數(shù)據(jù)庫(kù)連接。 如果用戶永遠(yuǎn)不要求顯示 Orders 或在計(jì)算中使用該數(shù)據(jù),則無(wú)需使用系統(tǒng)內(nèi)存或計(jì)算周期來(lái)創(chuàng)建它。 通過(guò)使用 Lazy 來(lái)聲明 Orders對(duì)象用于遲緩初始化,可以避免在不使用該對(duì)象時(shí)浪費(fèi)系統(tǒng)資源。
- 對(duì)象創(chuàng)建成本高,且希望將其創(chuàng)建推遲到其他高成本操作完成后。 例如,假定程序在啟動(dòng)時(shí)加載多個(gè)對(duì)象實(shí)例,但是只需立即加載其中一部分。 可以通過(guò)推遲初始化不需要的對(duì)象,直到創(chuàng)建所需對(duì)象,提升程序的啟動(dòng)性能。(來(lái)源官方)
示例
創(chuàng)建用戶類
public class User
{
public string Name { get; set; }
public int Age { get; set; }
public User() {
this.Name = "Name";
this.Age = 0;
}
}
默認(rèn)情況下,Lazy 對(duì)象是線程安全的。 也就是說(shuō),如果構(gòu)造函數(shù)沒(méi)有指定線程安全性的類型,該函數(shù)創(chuàng)建的 Lazy 對(duì)象是線程安全的。 在多線程方案中,訪問(wèn)線程安全 Lazy 對(duì)象的 Value 屬性的第一個(gè)線程會(huì)為所有線程上的所有后續(xù)訪問(wèn)對(duì)其初始化,且所有線程共享相同的數(shù)據(jù)。 因此,哪個(gè)線程初始化對(duì)象并不重要,爭(zhēng)用條件是良性的。
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();
}
}
| 對(duì)象的線程安全性 | LazyThreadSafetyMode mode 參數(shù) | 布爾 isThreadSafe 參數(shù) | 沒(méi)有線程安全性參數(shù) |
|---|---|---|---|
| 完全線程安全;一次只有一個(gè)線程嘗試初始化值。 | ExecutionAndPublication | true | 可以。 |
| 非線程安全。 | None | false | 不適用。 |
| 完全線程安全;線程爭(zhēng)用以初始化值。 | PublicationOnly | 不適用。 | 不適用。 |
其中IsValueCreated屬性是個(gè)Boolean類型,我們可以通過(guò)此屬性去確定當(dāng)前對(duì)象有沒(méi)有被初始化

調(diào)用后,進(jìn)行了創(chuàng)建操作

再說(shuō)說(shuō)Lazy中幾個(gè)構(gòu)造函數(shù),
- public Lazy (bool isThreadSafe):
isThreadSafe 的布爾參數(shù),該方法參數(shù)用于指定是否從多線程訪問(wèn) Value 屬性。 如果想要僅從一個(gè)線程訪問(wèn)屬性,則傳入 false 以獲取適度的性能優(yōu)勢(shì)。 如果想要從多線程訪問(wèn)屬性,則傳入 true 以指示 Lazy 實(shí)例正確處理爭(zhēng)用條件(初始化時(shí)一個(gè)線程引發(fā)異常)。
- public Lazy (LazyThreadSafetyMode mode):
提供線程安全模式。
- public Lazy (Func valueFactory):
lambda 表達(dá)式傳遞給新的 Lazy 對(duì)象的構(gòu)造函數(shù)。 下一次訪問(wèn) Value 屬性將導(dǎo)致新 Lazy 的初始化,并且其 Value 屬性此后會(huì)返回已分配給該屬性的新值。
參考:
https://docs.microsoft.com/en-us/dotnet/framework/performance/lazy-initialization
以上就是詳解C# Lazy Loading(懶加載)的詳細(xì)內(nèi)容,更多關(guān)于C# Lazy Loading(懶加載)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
使用C#實(shí)現(xiàn)網(wǎng)頁(yè)內(nèi)容保存為圖片并生成壓縮包
這篇文章主要為大家詳細(xì)介紹了如何使用C#實(shí)現(xiàn)網(wǎng)頁(yè)內(nèi)容保存為圖片并生成壓縮包,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-02-02
C#的正則表達(dá)式Regex類使用簡(jiǎn)明教程
這篇文章主要介紹了C#的正則表達(dá)式Regex類使用簡(jiǎn)明教程,分別講解了如何匹配、如何獲取匹配次數(shù)、如何獲取匹配內(nèi)容及捕獲的方法,需要的朋友可以參考下2014-08-08
C#實(shí)現(xiàn)XOR密碼(異或密碼)的示例代碼
XOR密碼(異或密碼)是一種簡(jiǎn)單的加密算法,它使用異或(XOR)操作來(lái)對(duì)明文和密鑰進(jìn)行加密和解密,本文為大家介紹了C#實(shí)現(xiàn)XOR密碼的相關(guān)知識(shí),希望對(duì)大家有所幫助2024-01-01
在WPF中合并兩個(gè)ObservableCollection集合
這篇文章介紹了在WPF中合并兩個(gè)ObservableCollection集合的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06
WPF仿三星手機(jī)充電界面實(shí)現(xiàn)代碼
這篇文章主要為大家詳細(xì)介紹了WPF仿三星手機(jī)充電界面實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-08-08
C#畫(huà)筆Pen保存和恢復(fù)圖形對(duì)象的設(shè)置方法
這篇文章主要介紹了C#畫(huà)筆Pen保存和恢復(fù)圖形對(duì)象的設(shè)置方法,實(shí)例分析了畫(huà)筆的保存save及恢復(fù)屬性Restore的相關(guān)使用技巧,需要的朋友可以參考下2015-06-06
C#操作Byte數(shù)組和十六進(jìn)制進(jìn)行互轉(zhuǎn)
這篇文章介紹了C#操作Byte數(shù)組和十六進(jìn)制進(jìn)行互轉(zhuǎn)的的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05
c# RSA非對(duì)稱加解密及XML&PEM格式互換方案
這篇文章主要介紹了c# RSA非對(duì)稱加解密及XML&PEM格式互換方案,幫助大家更好的理解和使用c#,感興趣的朋友可以了解下2020-12-12

