Mam kilka przypadków, w których używam ConcurrentDictionary<TKey, TValue>
do buforowania wartości, ale często muszę wykonać weryfikację wartości, aby zdecydować, czy dodać ją do pamięci podręcznej przy użyciu ConcurrentDictionary<TKey, TValue>.GetOrAdd(TKey, Func<TKey, TValue>)
.Jak mogę powiedzieć, że `ConcurrentDictionary.GetOrAdd` nie dodaje wartości?
Zazwyczaj wzdłuż linii:
private readonly ConcurrentDictionary<Type, ISomeObject> someObjectCache =
new ConcurrentDictionary<Type, ISomeObject>();
public ISomeObject CreateSomeObject(Type someType)
{
return someObjectCache.GetOrAdd(someType, type =>
{
if(!Attribute.IsDefined(someType, typeof(SomeAttribute))
// Do something here to avoid the instance from being added to
// `someObjectCache`
ISomeObject someObject;
// Typical factory functionality goes here
return someObject;
});
}
The Way I obsłużyć to dzisiaj jest wyjątek, który wydaje się działać dobrze, ale chciałbym czystsze podejście (może flagę mogę ustawić lub konkretną wartość mogę ustawić wartość zwracaną na), aby anulować GetOrAdd
z wewnątrz lambda (choć może to być realistycznie zastąpione metodą pełnowartościową).
Na podstawie mojego doświadczenia z innymi metodami podobnymi do LINQ, zwracanie null
spowoduje, że wartość zostanie dodana bez sprawdzania jako takiego (i przeczytanie IL dla GetOrAdd
wygląda na to, że spowoduje to ten sam problem), więc nie myśl, że to zadziała.
Czy jest jakiś sposób uniknięcia wyjątków, aby anulować dodawanie za pomocą GetOrAdd
?
To (i _ mam), ale gdy zagracie się to z wszystkimi niezbędnymi mechanizmami blokowania nici, staje się raczej brudny (nie, że mój nie wymaga blokowania ... tylko nie w tym samym stopniu). Szukam czystszego rozwiązania, a nie takiego, które wymaga efektywnej implementacji mojej własnej wersji 'ConcurrentDictionary'. –
Zaktualizowałem odpowiedź - GetOrAdd nie blokuje części Add, tylko w przypadku wewnętrznych bitów tablicy. Tak więc, jak widzę, nie powinieneś tu potrzebować żadnych zamków, jeśli twoim zamiarem jest tylko dodać walidację. –
Tak, przeczytałem tę część dokumentów, ale to wciąż nie jest to, czego szukam. Gdybym chciał napisać tak dużo kodu, sam sobie poradziłbym z blokadą. –