【问题标题】:Singleton with time-based lifespan具有基于时间的生命周期的单例
【发布时间】:2016-08-06 06:02:42
【问题描述】:

我正在尝试实现一个类似单例的类,它的生命周期是基于时间的。程序开始后每 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];
    }
}

结果:true

如何修复它以在每 5 秒的时间跨度内返回单独的实例?

【问题讨论】:

    标签: c# singleton


    【解决方案1】:

    我没有在列表和数组列表中摆弄索引,而是将您的实现更改为使用通用Dictionary&lt;tkey, tvalue&gt;,以便索引可以是一个简单的查找。请记住,这会不断添加项目,因此如果经常调用,您将耗尽内存。这里没有清理。

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

    【讨论】:

    • 太完美了,非常感谢。实际上,我最终确实最终自己使用了 Dictionary,但是模数而不是除以 5 一直对我造成破坏,我无法找出原因,感谢您指出这一点。
    猜你喜欢
    • 1970-01-01
    • 2016-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-29
    • 1970-01-01
    • 2012-12-03
    相关资源
    最近更新 更多