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