ディクショナリに指定されたキーの値が含まれていない場合にのみfalseを返しますか、それとも、別のスレッドが何かを追加/更新するなど、スレッドの競合状態が原因でfalseを返しますか?
コード内の質問:
ConcurrentDictionary<int, string> cd = new ConcurrentDictionary<int, string>();
// This might fail if another thread is adding with key value of 1.
cd.TryAdd(1, "one");
// Will this ever fail if no other thread ever removes with the key value of 1?
cd.TryRemove(1);
編集:指定されたキーの値が含まれていない場合にのみfalseを返すと思いますが、確実に確認したいと思います。
ミッチは正しいConcurrentDictionary
は競合状態に対して脆弱ではありませんが、あなたが尋ねている質問に対する答えは、キーが存在する場合はTryRemove
は機能し、true
を返します。
投稿したコードでは、TryRemove
は他の場所からアクセスされないローカル変数であるため、false
がcd
を返す方法はありません。しかし、他のコードにこのConcurrentDictionary
オブジェクトへの参照が与えられていて、別のスレッドでキーを削除している場合、TryRemove
がfalse
を返す可能性があります。ただし、キーがすでに削除されているため、辞書に対して他のアクションが実行されていて、キーが何らかの理由で「スタック」されているためではありません。
ConcurrentDictionary は競合状態の影響を受けません。それがあなたがそれを使う理由です。
戻り値
オブジェクトが正常に削除された場合はtrue。それ以外の場合はfalse。
もう1つの注意点:
// This might fail if another thread is adding with key value of 1. cd.TryAdd(1, "one");
このコメントは正しくなく、「試してみる」とはどういう意味かについて同じ誤解を受けている可能性があります。これは、同時に追加しようとする試みではなく、値がキー1
ですでに追加されているかどうかです。
標準のDictionary<TKey,TValue>
を検討してください。同等のコードは次のようになります。
if (!d.Contains(1))
d.Add(1, "one");
これには2つの操作が必要です。 cd
には、Contains
とAdd
の呼び出しの間にキー1
が追加された値が含まれる場合があるため、このようなAPIをスレッドセーフに設計する方法はありません。その結果、Add
がスローされます。
並行コレクションには、これらのテストと実行のペアを単一のAPIの背後にある単一のアトミック操作に論理的にバンドルするAPIがあります。