C# Throttle Function

Date: 2024-02-19
public class CachedThrottle<T>
{
    private readonly Func<Task<T>> fn;
    private T data = default(T);
    private DateTime? Last = null;
    private readonly TimeSpan ThrottleTime;
    private readonly object locker = new();

    public CachedThrottle(Func<Task<T>> initialFn, TimeSpan throttleTime)
    {
        fn = initialFn;
        ThrottleTime = throttleTime;
    }

    public async Task<T> Load()
    {
        Last = DateTime.Now;
        try
        {
            data = await fn();
        }
        catch (System.Exception)
        {
            Last = null;
            throw;
        }
        return data;
    }

    public T Get()
    {
        TriggerUpdate();
        return data;
    }

    public async Task<T> GetAsync()
    {
        if (IsElapsed())
        {
            Last = DateTime.Now;
            return await Load();
        }
        return data;
    }

    public void TriggerUpdate()
    {
        lock (locker)
        {
            if (IsElapsed())
            {
                Last = DateTime.Now;
                Task.Run(Load);
            }
        }
    }

    public bool IsElapsed() => Last == null || (DateTime.Now - Last).Value > ThrottleTime;
}

// Example
public class Program
{
    public static CachedThrottle<string> Content = new(() => { Console.WriteLine("ReadingFile"); return File.ReadAllTextAsync(@"C:\temp\test.txt"); }, TimeSpan.FromSeconds(2));

    public static async Task Main()
    {
        await Content.Load();
        Console.WriteLine($"A: {Content.Get()}");
        Console.WriteLine($"B: {Content.Get()}");
        await Task.Delay(1000);
        Console.WriteLine($"C: {Content.Get()}");
        await Task.Delay(2000);
        Console.WriteLine($"D: {Content.Get()}");
    }
}
82920cookie-checkC# Throttle Function