Last active
July 18, 2024 15:26
-
-
Save mvacha/12bbe6da28c1d672926a51a2ad4c05ef to your computer and use it in GitHub Desktop.
Cached Tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// See https://aka.ms/new-console-template for more information | |
using System.Runtime.CompilerServices; | |
Console.WriteLine("Program started"); | |
var cache = new Dictionary<string, object>(); | |
//Use lambda, so the task does not start immediately | |
Func<Task<string>> taskFactory = async () => | |
{ | |
Console.WriteLine("Task started"); | |
await Task.Delay(1000); // Simulate a delay | |
return "Task result"; | |
}; | |
//V1: use CachedTask class | |
var cachedTask = new CachedTask<string>("key", taskFactory, cache); | |
Console.WriteLine(await cachedTask); | |
//V2: use extension method | |
var cachedTask2 = taskFactory().Cached("key", cache); | |
Console.WriteLine(await cachedTask2); | |
public class CachedTask<T>(string key, Func<Task<T>> taskFactory, IDictionary<string, object> cache) | |
{ | |
private readonly string _key = key; | |
private readonly Func<Task<T>> _taskFactory = taskFactory; | |
private readonly IDictionary<string, object> _cache = cache; | |
public async Task<T> GetValueAsync() | |
{ | |
if (_cache.TryGetValue(_key, out object? value)) | |
return (T)value; | |
var result = await _taskFactory().ConfigureAwait(false); | |
_cache[_key] = result; | |
return result; | |
} | |
//Make CachedTask awaitable | |
public TaskAwaiter<T> GetAwaiter() => GetValueAsync().GetAwaiter(); | |
} | |
public static class TaskExtensions | |
{ | |
public static Task<T> Cached<T>(this Task<T> task, string key, IDictionary<string, object> cache) | |
{ | |
if (cache.TryGetValue(key, out object? value)) | |
return Task.FromResult((T)value); | |
return task.ContinueWith(t => | |
{ | |
cache[key] = t.Result; | |
return t.Result; | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment