2016-04-14 7 views
0

Ich versuche eine Singleton-ähnliche Klasse zu implementieren, die eine lebenslange Lebensdauer hat. Instanzen, die in jedem 5-Sekunden-Zeitraum vom Start des Programms erstellt werden, sollten die gleichen sein wie in einem normalen Singleton, und zwischen den verschiedenen 5-Sekunden-Bereichen sollten verschiedene Singleton-Instanzen vorhanden sein. Ich habe eine Liste erstellt, in der die Singleton-Instanzen statt des typischen statischen Instanzfeldes gespeichert werden. Allerdings bekomme ich immer noch die gleiche Instanz, wenn ich es teste. Hier ist der Code:Singleton mit zeitbasierter Lebensdauer

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]; 
    } 
} 

Ergebnis: true

Wie kann ich das Problem beheben für jede 5-Sekunden-Zeitspanne separate Instanzen zurück?

Antwort

1

Statt der Fummelei mit den Indizes in einer Liste und Arraylist habe ich Ihre Implementierung geändert, um eine generische Dictionary<tkey, tvalue> stattdessen verwenden, so dass der Index eine einfache Suche sein kann. Denken Sie daran, dass dadurch Elemente hinzugefügt werden. Wenn Sie also oft genug angerufen werden, haben Sie keinen Speicher mehr. Es gibt keine Aufräumarbeiten hier.

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

Das ist perfekt, vielen Dank. Letztendlich habe ich sogar selbst mit Dictionary gearbeitet, aber das Modulo anstelle der Division durch 5 hat es für mich immer wieder ruiniert und ich konnte nicht herausfinden warum, danke, dass ich darauf hingewiesen habe. – Marcin