var capitals = new ConcurrentDictionary<string, string>{
["Norway"] = "Oslo",
["Denmark"] = "Copenhagen",
["Sweden"] = "Stockholm",
["Faroe Islands"] = "Torshamn",
["Finland"] = "Helsinki",
["Iceland"] = "Reykjavik"
};
//make a snapshot of the concurrent dictionary first
var capitalsSnapshot = capitals.ToArray();
//do some modifications
foreach (var capital in capitals){
capitals[capital.Key] = capital.Value.ToUpper();
}
foreach (var capital in capitalsSnapshot)
{
Console.WriteLine($"The capital in {capital.Key} is {capital.Value}");
}
This outputs:
The capital in Denmark is Copenhagen
The capital in Sweden is Stockholm
The capital in Faroe Islands is Torshamn
The capital in Norway is Oslo
The capital in Finland is Helsinki
The capital in Iceland is Reykjavik
The snapshot of the concurrent collection was not modified by the modifications done. Let's look at the concurrent collection again and iterate upon it.
foreach (var capital in capitals)
{
Console.WriteLine($"The capital in {capital.Key} is {capital.Value}");
}
This outputs:
Enumerate capitals in concurrent array - just enumerating with ToArray() - elements can be changed while enumerating. Faster, but more unpredictable
The capital in Denmark is COPENHAGEN
The capital in Sweden is STOCKHOLM
The capital in Faroe Islands is TORSHAMN
The capital in Norway is OSLO
The capital in Finland is HELSINKI
The capital in Iceland is REYKJAVIK
As we can see, the concurrent dictionary has modified its contents and this shows that we can get modifications upon iterating collections. If you do want to get consistent results, using a snapshot should be desired. But note that this will lock the entire collection and involve costly operations of copying the contents. If you do do concurrent collection snapshots, keep the number of snapshots to a minimum and iterate upon these snapshots, preferable only doing one snapshot in one single place in the method for the specific concurrent dictionary.
No comments:
Post a Comment