tutaj na przepełnienie stosu mam found kod, który memoizes funkcje jednego argumentu:Jak wykonać funkcję zapamiętywania funkcji wątku w języku C#?
static Func<A, R> Memoize<A, R>(this Func<A, R> f)
{
var d = new Dictionary<A, R>();
return a=>
{
R r;
if (!d.TryGetValue(a, out r))
{
r = f(a);
d.Add(a, r);
}
return r;
};
}
Chociaż ten kod wykonuje swoją pracę dla mnie, nie jest on czasem gdy funkcja memoized jest wywoływana z wielu wątków jednocześnie: metoda Add
zostaje wywołana dwukrotnie z tym samym argumentem i zgłasza wyjątek.
Jak wykonać zapamiętywanie wątku w bezpieczny sposób?
Zauważ, że 'GetOrAdd' nie zapobiega całkowicie wywołaniu f więcej niż jeden raz dla danego argumentu; gwarantuje jedynie, że wynik tylko * jeden * wywołań zostanie dodany do słownika. Można uzyskać więcej niż jedno wywołanie w przypadku jednoczesnego sprawdzania pamięci podręcznej wątków przed dodaniem wartości buforowanej. Często nie warto się tym martwić, ale wspominam o tym w przypadku, gdy wywołanie ma niepożądane skutki uboczne. –
@JamesWorld Tak, zgadza się. Edytowana odpowiedź odzwierciedla to, dziękuję! – Gman
Jestem nieco zdezorientowany - czy nie jest "cache" tutaj zmienną lokalną? Za każdym razem, gdy wywoływana jest 'ThreadsafeMemoize()', czy nie utworzy on nowego słownika? – dashnick