値のキャッシングにConcurrentDictionary<TKey, TValue>
を使用するいくつかのケースがありますが、多くの場合、ConcurrentDictionary<TKey, TValue>.GetOrAdd(TKey, Func<TKey, TValue>)
を使用してキャッシュに追加するかどうかを決定するために値の検証を実行する必要があります。`ConcurrentDictionary.GetOrAdd`に値を追加しないように指示する方法はありますか?
通常の線に沿って:
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;
});
}
今日はこれを処理する方法は、正常に動作するように見える例外をスローすることですが、私はクリーンなアプローチが欲しい(私は設定することができます多分フラグまたは特定の値を返すように設定してラムダ内からGetOrAdd
を取り消すことができます(ただし、現実的には完全な方法で置き換えることができます)。
null
を返す他のLINQメソッドの経験に基づいて、チェックされずに値が追加されます(GetOrAdd
のILを読み取ると、同じ問題が発生するようです)。それがうまくいくとは思わない。
GetOrAdd
を使用して例外を使用して追加をキャンセルしないようにする方法はありますか?
しかし、いったん必要なすべてのスレッドロック機構でそれを乱雑にすると、むしろ乱雑になります(私のものはロックを必要としません...同じ程度ではありません)。私は、より洗練されたソリューションを探しています。自分のバージョンのConcurrentDictionaryを効果的にロールバックする必要はありません。 –
私の答えを更新 - GetOrAddは、内部配列ビットを扱う場合にのみ、Add部分をロックしません。だから、あなたが意図しているのは、検証だけを追加することだとすれば、ここにはロックが必要ないはずです。 –
はい、私はその部分を読んだことがありますが、これはまだ私が探しているものではありません。あまりにも多くのコードを書いたければ、私は自分でロックを処理するでしょう。 –