Is this better:
public void Test()
{
ConcurrentDictionary<int, string> dictionary = new ConcurrentDictionary<int, string>();
dictionary.TryAdd(0, "A");
dictionary.TryAdd(1, "B");
dictionary.TryAdd(2, "A");
dictionary.TryAdd(3, "D");
foreach (var item in dictionary)
{
string foundItem;
if (dictionary.TryGetValue(item.Key, out foundItem))
{
if (foundItem == "A")
{
if (dictionary.TryRemove(item.Key, out foundItem))
{
// Success
}
}
}
}
}
Than this?:
public void Test2()
{
ConcurrentDictionary<int, string> dictionary = new ConcurrentDictionary<int, string>();
dictionary.TryAdd(0, "A");
dictionary.TryAdd(1, "B");
dictionary.TryAdd(2, "A");
dictionary.TryAdd(3, "D");
foreach (var item in dictionary)
{
string foundItem;
if (item.Value == "A")
{
if (dictionary.TryRemove(item.Key, out foundItem))
{
// Success
}
}
}
}
This method will be accessed by multiple thread.
My confusion is, whenever I want to remove an item, I try to get it first, then remove it. But in the first place, I have used foreach
loop, meaning I have already get the item. Any idea would be appreciated.
I don't see any benefit in the first approach. I'd just use LINQ to find the items though:
foreach (var entry in dictionary.Where(e => e.Value == "A"))
{
string ignored;
// Do you actually need to check the return value?
dictionary.TryRemove(entry.Key, out ignored);
}
Of course, you need to consider what you want to happen if another thread adds a new entry with value "A"
or updates an existing entry (possibly to make the value "A"
, possibly to make the value not-"A"
while you're iterating... does it matter to you whether or not that entry is removed? It's not guaranteed what will happen. (The iterator doesn't take a snapshot, but isn't guaranteed to return entirely up-to-date data either.)
You may want to check that the value you've removed really is "A"
by checking the variable I've called ignored
afterwards. It really depends on your context. When you've got multiple threads modifying the map, you need to think that anything can happen at any time - within the operations that your code actually performs.
There's also the fact that you're effectively having to trawl through the whole dictionary... are you looking up by key elsewhere?
See more on this question at Stackoverflow