2016-04-14 7 views
0

シングルトンのようなクラスを実装しようとしていますが、それは時間に基づいて寿命があります。プログラムの開始から5秒ごとに作成されるインスタンスは、通常のシングルトンの場合と同じでなければならず、異なる5秒のスパン間で異なるシングルトンインスタンスが存在する必要があります。私が思いついたのは、典型的な静的インスタンスフィールドではなく、シングルトンインスタンスを格納するリストです。しかし、私はそれをテストするときに同じインスタンスを取得しています。時間ベースの寿命を持つシングルトン

class Program 
    { 
     static void Main(string[] args) 
     { 
      TimedSingleton t1 = TimedSingleton.Instance(); 
      Thread.Sleep(5500); 
      TimedSingleton t2 = TimedSingleton.Instance(); 

     Console.WriteLine(t1 == t2); 

     Console.ReadKey(); 
    } 
} 

class TimedSingleton 
{ 
    private static ArrayList _instancesArrayList = new ArrayList(); 
    private static List<int> AddedPositions = new List<int>(); 

    private static DateTime _startTime = DateTime.Now; 

    protected TimedSingleton() 
    { 
    } 

    public static TimedSingleton Instance() 
    { 
     int index = (int) DateTime.Now.Subtract(_startTime).TotalSeconds%5; 

     if (AddedPositions.Count == 0) 
     { 
      _instancesArrayList.Add(new TimedSingleton()); 
      AddedPositions.Add(index); 
      return (TimedSingleton)_instancesArrayList[index]; 
     } 

     if (AddedPositions.Contains(index)) 
     { 
      return (TimedSingleton) _instancesArrayList[index]; 
     } 

     AddedPositions.Add(index); 
     _instancesArrayList.Add(new TimedSingleton()); 
     return (TimedSingleton) _instancesArrayList[index]; 
    } 
} 

結果::私はそれが各5秒のタイムスパンのための別のインスタンスを返すように修正することができますどのようにtrue

ここでは、コードですか?

答えて

1

リストとarraylistのインデックスを手にするのではなく、代わりに汎用のDictionary<tkey, tvalue>を使用するように実装を変更しました。インデックスは単純な検索になる可能性があります。これはアイテムを追加し続けるので、頻繁に呼び出されるとメモリが足りなくなることに注意してください。ここでクリーンアップはありません。

class TimedSingleton 
{ 
    // have a dictonary to hold the seconds 
    // and the instance so we can lookup 
    private static Dictionary<int, TimedSingleton> AddedPositions = new Dictionary<int, TimedSingleton>(); 

    private static DateTime _startTime = DateTime.Now; 

    protected TimedSingleton() 
    { 
    } 

    public static TimedSingleton Instance() 
    { 
     // divide by 5 
     int index = (int)DateTime.Now.Subtract(_startTime).TotalSeconds/5; 
     Debug.WriteLine(index); 

     // 
     TimedSingleton result; 
     // if you're going to multhreed this 
     lock(AddedPositions) 
     { 
      // try to get the index seconds ... 
      if (!AddedPositions.TryGetValue(index,out result)) 
      { 
       // not happened 
       Debug.WriteLine("Created new instance"); 
       result = new TimedSingleton(); 
       // store it for later 
       AddedPositions.Add(index, result); 
      } 
      else 
      { 
       // result has now a previous instance 
       Debug.WriteLine("from cache"); 
      } 
     } 
     return result; 
    } 
} 
+0

これは完璧です。ありがとうございます。私は実際に辞書を使って最終的に結局自分自身を終了しましたが、5の除算の代わりにモジュロがそれを台無しにしていました。 – Marcin