public async Task GetCacheItemAsync()

in code/KustoCopyConsole/Concurrency/AsyncCache.cs [33:66]


        public async Task<T> GetCacheItemAsync(CancellationToken ct)
        {
            while (true)
            {
                var cacheNode = _cacheNode;

                if (cacheNode.IsItemAvailable && cacheNode.ExpirationTime > DateTime.Now)
                {
                    return cacheNode.Item!;
                }
                else
                {   //  Try to "enter" the cache node:  this might be a competition
                    if (cacheNode.EnterSource.TrySetResult())
                    {
                        var result = await _asyncFetchFunction();
                        var newCacheNode = new CacheNode(
                            new TaskCompletionSource(),
                            new TaskCompletionSource(),
                            true,
                            result.Item2,
                            DateTime.Now.Add(result.Item1));

                        Interlocked.Exchange(ref _cacheNode, newCacheNode);
                        cacheNode.ExitSource.SetResult();

                        return newCacheNode.Item!;
                    }
                    else
                    {   //  Fail to enter the cache node:  another thread will fetch the item
                        await cacheNode.ExitSource.Task;
                    }
                }
            }
        }