initial commit

This commit is contained in:
Kukks
2023-01-16 10:31:48 +01:00
parent 136273406c
commit 25ccd99558
171 changed files with 10592 additions and 0 deletions

View File

@@ -0,0 +1,38 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace BTCPayServer.Plugins.Wabisabi;
public static class Extensions
{
/// <summary>
/// Returns an existing task from the concurrent dictionary, or adds a new task
/// using the specified asynchronous factory method. Concurrent invocations for
/// the same key are prevented, unless the task is removed before the completion
/// of the delegate. Failed tasks are evicted from the concurrent dictionary.
/// </summary>
public static Task<TValue> GetOrAddAsync<TKey, TValue>(
this ConcurrentDictionary<TKey, Task<TValue>> source, TKey key,
Func<TKey, Task<TValue>> valueFactory)
{
if (!source.TryGetValue(key, out var currentTask))
{
Task<TValue> newTask = null;
var newTaskTask = new Task<Task<TValue>>(async () =>
{
try { return await valueFactory(key).ConfigureAwait(false); }
catch
{
source.TryRemove(KeyValuePair.Create(key, newTask));
throw;
}
});
newTask = newTaskTask.Unwrap();
currentTask = source.GetOrAdd(key, newTask);
if (currentTask == newTask) newTaskTask.Start(TaskScheduler.Default);
}
return currentTask;
}
}