50 lines
1.7 KiB
C#
50 lines
1.7 KiB
C#
|
using System;
|
|||
|
|
|||
|
namespace NadekoBot.Core.Common.Caching
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// A caching object which loads its value with a factory method when it expires.
|
|||
|
/// </summary>
|
|||
|
/// <typeparam name="T">Type of the value which is cached.</typeparam>
|
|||
|
public class FactoryCache<T> : IFactoryCache
|
|||
|
{
|
|||
|
public DateTime LastUpdate { get; set; } = DateTime.MinValue;
|
|||
|
private readonly object _locker = new object();
|
|||
|
private TimeSpan _expireAfter;
|
|||
|
private readonly Func<T> _factory;
|
|||
|
private T Value;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Creates a new factory cache object.
|
|||
|
/// </summary>
|
|||
|
/// <param name="factory">Method which loads the value when it expires or if it's not loaded the first time.</param>
|
|||
|
/// <param name="expireAfter">Time after which the value will be reloaded.</param>
|
|||
|
/// <param name="loadImmediately">Should the value be loaded right away. If set to false, value will load when it's first retrieved.</param>
|
|||
|
public FactoryCache(Func<T> factory, TimeSpan expireAfter,
|
|||
|
bool loadImmediately = false)
|
|||
|
{
|
|||
|
_expireAfter = expireAfter;
|
|||
|
_factory = factory;
|
|||
|
if (loadImmediately)
|
|||
|
{
|
|||
|
Value = _factory();
|
|||
|
LastUpdate = DateTime.UtcNow;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public T GetValue()
|
|||
|
{
|
|||
|
lock (_locker)
|
|||
|
{
|
|||
|
if (DateTime.UtcNow - LastUpdate > _expireAfter)
|
|||
|
{
|
|||
|
LastUpdate = DateTime.UtcNow;
|
|||
|
return Value = _factory();
|
|||
|
}
|
|||
|
|
|||
|
return Value;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|