2017-02-21 48 views
0

使用Lazy<T>屬性緩存,訪問該屬性與支持字段或沒有支持字段之間有任何行爲差異?也許任何表現擊中?懶惰<T>緩存帶/不帶後臺字段 - 性能?

下面的示例代碼是在內部屬性中緩存Autofac IoC container。該代碼僅用於初始化一次。不管它是否遵循正確的IoC/DI原則,都不是問題。

實施例1:

internal static ILifetimeScope Bootstrap = new Lazy<ILifetimeScope>(InitializeContainer, LazyThreadSafetyMode.ExecutionAndPublication).Value; 

private static ILifetimeScope InitializeContainer() 
{ 
    ContainerBuilder builder = new ContainerBuilder(); 
    //Registration logic... 
    return builder.Build(); 
} 

實施例2:

private static readonly Lazy<ILifetimeScope> _container = new Lazy<ILifetimeScope>(InitializeContainer, LazyThreadSafetyMode.ExecutionAndPublication); 

internal static ILifetimeScope Container => _container.Value; 

private static ILifetimeScope InitializeContainer() 
{ 
    ContainerBuilder builder = new ContainerBuilder(); 
    //Registration logic... 
    return builder.Build(); 
} 

編輯1 我在具有容器的緩存值比較有興趣,使得它每次訪問該屬性時都不會被初始化。我不在乎初始化是否被延遲。

+0

「不管它是否遵循正確的IoC/DI原則都不是問題。」不是問題,而是總是有些值得質疑的問題。 – Steven

+0

並不多。我已經嘗試訪問這兩個示例中的屬性,並確保它只運行一次初始化工廠。許多'懶惰的'緩存示例都顯示了支持字段,我想知道爲什麼,因爲我認爲第一個示例更漂亮。例如。 http://stackoverflow.com/questions/5134786/cached-property-vs-lazyt?rq=1 –

+1

第一個等同於編寫'Bootstrap = InitializeContainer();'。它不會將初始化委託給您訪問容器的時間,只是包含類的靜態構造函數運行的時間。在這種情況下使用'懶惰'沒什麼意義。 – Luaan

回答

1

IMO在第一個示例中調用.Value在該行上使得懶惰幾乎沒有用處,因爲它在實例化惰性對象的下一次實例化容器時,做這件事的意義是什麼懶惰如果創建的對象不會推遲到以後的時間。因此,如果您需要延遲對象的創建,那麼我認爲第二個示例更好,因爲直到第一次調用容器時容器纔會被初始化。

另一個例子是一個字段,它不會這樣做.Value最終與第二個例子相同,但是您必須在任何想要使用它的地方調用.Value,使它有點不舒服。

internal static Lazy<ILifetimeScope> Bootstrap = new Lazy<ILifestimeScope>(InitializeContainer, LazyThreadSafetyMode.ExecutionAndPublication);

所以,如果我是你,我會去第二個例子是既舒適調用,使有用的延遲加載,但請記住,第一時間打電話給則初始化容器,第一次使用它會比第一個例子花費更多的時間來完成動作

+0

我最感興趣的是有一個緩存的值,而不是推遲創作。 –

+0

然後它幾乎相同,但我會評估您的容器是否必須是線程安全的。如果是這樣,那麼使用Lazy,如果沒有,可以使用靜態構造函數;懶惰對靜態ctor有一點開銷,但是如果配置正確,可以確保線程安全。而在這兩個例子之間,我不認爲使用這兩個例子的性能會有重大影響 – fmaccaroni