I wanted to test parallel adding and removing to a ConcurrentDictionary
.
I have the following code in my test class:
[TestMethod]
public void T_Parallel_Removing
{
var management = new Management();
List<Task> AddTasks = new List<Task>();
List<Task> RemoveTasks = new List<Task>();
var units = new List<Unit>();
for (int i = 0; i < 30; i++)
{
var unit = new Unit();
units.Add(unit);
AddTasks.Add(Task.Run(() => AddUnit(management, unit)));
}
Task.WaitAll(AddTasks.ToArray());
}
The AddUnit
and RemoveUnit
methods:
public void AddUnit(Management m, Unit u,)
{
management .AddPlantUnit(u, "",);
}
public void RemoveUnit(Management m, Unit u)
{
m.RemovePlantUnit(u.Adress);
Console.WriteLine(u.Adress);
}
This works perfectly fine. But when i start Removing something odd happens (ignore the int areas, I somehow thought that they are a part of the problem, but they are not)
for (int i = 0; i < 29; i++)
{
RemoveTasks .Add(Task.Run(() => RemoveUnit(management, units[i])));
}
Here i get always the same address and the output if for every task the same.
But if I use following code:
RemoveTakes.Add(Task.Run(() => RemoveUnit(management, units[0])));
RemoveTasks.Add(Task.Run(() => RemoveUnit(management, units[1])));
RemoveTasks.Add(Task.Run(() => RemoveUnit(management, units[2])));
RemoveTasks.Add(Task.Run(() => RemoveUnit(management, units[3])));
RemoveTasks.Add(Task.Run(() => RemoveUnit(management, units[4])));
RemoveTasks.Add(Task.Run(() => RemoveUnit(management, units[5])));
It works without a problem. If I add some dummy Code or a Thread.Sleep(1)
into the for loop it also works (every task gets a different address)
Can someone explain this behaviour?