中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

基礎才是重(zhong)中(zhong)之(zhi)重(zhong)~延遲初始化

 回到目錄

概(gai)念:一個對(dui)象的延(yan)遲(chi)初始化(hua)(也稱延(yan)遲(chi)實例化(hua))意味(wei)著該對(dui)象的創建將會延(yan)遲(chi)至第一次(ci)使用(yong)該對(dui)象時。 延遲初始化主要(yao)用(yong)于提高性能,避免浪費計(ji)算,并減少(shao)程序內存要(yao)求。

以下是(shi)最常見的方案:

  • 有一個對象的(de)創建開銷很(hen)大(da)時(shi),應用(yong)程序可能不會(hui)使用(yong)它。 例如,假定您在內存中有一個 Customer 對象,該對象的 Orders 屬性返回一個 Orders 對象。 初始化 Orders 對象可能需要創建 Orders 對象的一個大數組(Orders[]),并可能需要數據庫連接。 如果用戶從不訪問 Orders 屬性,則沒有理由使用系統內存或計算周期來創建 Orders 對象。 通過使用 Lazy<Orders>Orders 對象聲明為延遲初始化,可以避免在不使用該對象的情況下浪費系統資源。

  • 有一個對象(xiang)的創建(jian)開銷很大,您想要(yao)將創建(jian)它的時(shi)間延遲到完(wan)成其他開銷大的操作之后(hou)。 例(li)如,假定您的應(ying)用程序(xu)在啟動(dong)時(shi)加載若干個對(dui)象實(shi)例(li),但(dan)只有一(yi)些對(dui)象實(shi)例(li)需要立即執行。 通過將不必(bi)要的對象(xiang)的初始化延遲到已(yi)創建必(bi)要的對象(xiang)之后,可以提高應用程序的啟動性(xing)能。

    盡管您可以編寫自己的代碼來執行遲緩初始化,但我們建議改用 類。 支持線程安全(在一個線程中創建實例后,對其它線也是共享的),并提供一致的異常傳播策略。

    基本語法:

    1 Lazy<Orders> Orders=new Lazy<Orders>();

    另外,還可以在 構造函數中傳遞一個委托,用于在創建時調用包裝類的特定構造函數重載,并執行所需的任何其他初始化步驟,如以下示例中所示。

    1 Lazy<Orders> _orders = new Lazy<Orders>(() => new Orders(OrderSorted.CreateDate)); //可以重載指定的構造函數,如用來實(shi)現(xian)一種排序(xu)規則

    在創建 Lazy 對象之后,在第一次訪問 實例的 屬性之前,將不會創建 Orders 的實例。 在第(di)一次訪(fang)問(wen)包(bao)裝(zhuang)類型(xing)時,將會(hui)創建并返回該包(bao)裝(zhuang)類型(xing),并將其存(cun)儲起(qi)來(lai)(lai)以備任何(he)將來(lai)(lai)的訪(fang)問(wen)。

    1 // 當(dang)滿足一種(zhong)條件時,再去創建(jian)orders對象(xiang)
    2 if (displayOrders == true)
    3 {
    4     DisplayOrders(_orders.Value.OrderData);
    5 }
    6 else
    7 {
    8     // Don't waste resources getting order data.
    9 }

    線程安全初始化

    默認情況下, 對象是線程安全的。 這意味著如果構造函數未指定線程安全性的類型,它創建的 對象都是線程安全的。 在多線程方案中,要訪問線程安全的 對象的 屬性的第一個線程將為所有線程上的所有后續訪問初始化該對象,并且所有線程都共享相同數據。 因(yin)此,由哪個線程初始化對(dui)象并不(bu)重要,爭用條件(jian)將是良(liang)性的。

     1 // Initialize the integer to the managed thread id of the 
     2 // first thread that accesses the Value property.
     3 Lazy<int> number = new Lazy<int>(() => 
     4      Thread.CurrentThread.ManagedThreadId);
     5 
     6 Thread t1 = new Thread(() => 
     7     Console.WriteLine("number on t1 = {0} ThreadID = {1}",
     8                       number.Value, Thread.CurrentThread.ManagedThreadId));
     9 t1.Start();
    10 
    11 Thread t2 = new Thread(() => 
    12     Console.WriteLine("number on t2 = {0} ThreadID = {1}",
    13                       number.Value, Thread.CurrentThread.ManagedThreadId));
    14 t2.Start();
    15 
    16 Thread t3 = new Thread(() => 
    17     Console.WriteLine("number on t3 = {0} ThreadID = {1}", number.Value,
    18                       Thread.CurrentThread.ManagedThreadId));
    19 t3.Start();
    20 
    21 // Ensure that thread IDs are not recycled if the 
    22 // first thread completes before the last one starts.
    23 t1.Join();
    24 t2.Join();
    25 t3.Join();
    26 
    27 /* Sample Output:
    28     number on t1 = 11 ThreadID = 11
    29     number on t3 = 11 ThreadID = 13
    30     number on t2 = 11 ThreadID = 12
    31     Press any key to exit.
    32 */

    若要通過使用延遲初始化來實現一個公共屬性,請將該屬性的支持字段定義為 對象,并從該屬性的 get 訪問器返回 屬性。

     1 class Customer
     2 {
     3     private Lazy<Orders> _orders;
     4     public string CustomerID {get; private set;}
     5     public Customer(string id)
     6     {
     7         CustomerID = id;
     8         _orders = new Lazy<Orders>(() =>
     9         {
    10             // You can specify any additonal 
    11             // initialization steps here(這個(ge)Orders不會(hui)應該Customer的(de)實例化,而被實例化,它只會(hui)在使時,才會(hui)被實例化)
    12             return new Orders(this.CustomerID);
    13         });
    14     }
    15 
    16     public Orders MyOrders
    17     {
    18         get
    19         {
    20             // Orders is created on first access here.
    21             return _orders.Value;
    22         }
    23     }
    24 }

    延時實例化,在大對象時使用比較多,使用Lazy<(Of <(T>)>)我們還可以實現一種泛型的單例基類,看代碼:

     1  /// <summary>
     2     /// 泛型單例(li)基(ji)類
     3     /// </summary>
     4     public abstract class Singleton<TEntity> where TEntity : class
     5     {
     6         private static readonly Lazy<TEntity> _instance
     7           = new Lazy<TEntity>(() =>
     8           {
     9               var ctors = typeof(TEntity).GetConstructors(
    10                   BindingFlags.Instance
    11                   | BindingFlags.NonPublic
    12                   | BindingFlags.Public);
    13               if (ctors.Count() != 1)
    14                   throw new InvalidOperationException(String.Format("Type {0} must have exactly one constructor.", typeof(TEntity)));
    15               var ctor = ctors.SingleOrDefault(c => c.GetParameters().Count() == 0 && c.IsPrivate);
    16               if (ctor == null)
    17                   throw new InvalidOperationException(String.Format("The constructor for {0} must be private and take no parameters.", typeof(TEntity)));
    18               return (TEntity)ctor.Invoke(null);
    19           });
    20 
    21         public static TEntity Instance
    22         {
    23             get { return _instance.Value; }
    24         }
    25     }

     

      回到目錄

    參考 文獻:

    //technet.microsoft.com/zh-cn/magazine/dd997286%28VS.95%29.aspx

     

    返回目錄  基礎才是重中之重系列~目錄(永久更新中)

     

     

     

     

     

     

posted @ 2012-06-12 11:38  張占嶺  閱讀(6106)  評論(12)    收藏  舉報