Lazy with expiration time

前端 未结 3 672
春和景丽
春和景丽 2021-02-13 21:29

I want to implement an expiration time on a Lazy object. The expiration cooldown must start with the first retrieve of the value. If we get the value, and the expiration time is

3条回答
  •  滥情空心
    2021-02-13 21:52

    I agree with the other commenters that you probably shouldn't touch Lazy at all. Lazy isn't very complicated if you ignore the multiple thread-safety options, so just implement it from scratch.

    I quite like the idea by the way, although I don't know if I'd be comfortable using it as a general purpose caching strategy. It might be sufficient for some of the simpler scenarios.

    Here's my stab at it. If you don't need it to be thread-safe you can just remove the locking stuff. I don't think it's possible to use the double-checking lock pattern here because of the chance that the cached value may be be invalidated inside the lock.

    public class Temporary
    {
        private readonly Func factory;
        private readonly TimeSpan lifetime;
        private readonly object valueLock = new object();
    
        private T value;
        private bool hasValue;
        private DateTime creationTime;
    
        public Temporary(Func factory, TimeSpan lifetime)
        {
            this.factory = factory;
            this.lifetime = lifetime;
        }
    
        public T Value
        {
            get
            {
                DateTime now = DateTime.Now;
                lock (this.valueLock)
                {
                    if (this.hasValue)
                    {
                        if (this.creationTime.Add(this.lifetime) < now)
                        {
                            this.hasValue = false;
                        }
                    }
    
                    if (!this.hasValue)
                    {
                        this.value = this.factory();
                        this.hasValue = true;
    
                        // You can also use the existing "now" variable here.
                        // It depends on when you want the cache time to start
                        // counting from.
                        this.creationTime = Datetime.Now;
                    }
    
                    return this.value;
                }
            }
        }
    }
    

提交回复
热议问题