I have a multidimensional array with mutexes, and I use them so some critical sections. At the end is sketch of my class.
Now, I tried to add and delete characters in different threads without stopping, and at the same time getting characters from another thread to test if my server will work properly, but I get an exception when I try to get a character that says something like this: “Collection was modified during foreach..”
Anyone knows why? I have read the documentation of the lock statement in MSDN and it should work, I don’t know what I am doing wrong. Maybe new object[] can’t be used as a mutex?
If lock(objectReference) shouldn’t be used in this case, what should I use instead?
Sketch of my class:
partial class MapCharacter
{
public MapCharacter()
{
mutexes = new object[5, 5];
for (int x = 0; x < 5; x++)
{
for (int y = 0; y < 5; y++)
{
mutexes[x, y] = new object();
}
}
}
object[,] mutexes;
public object RequestMutex(int x, int y)
{
return mutexes[x, y];
}
public void RemoveCharacter(Character characterToRemove)
{
lock (RequestMutex(characterToRemove.X, characterToRemove.Y))
{
loggedCharacters.Remove(characterToRemove);
}
}
public void AddCharacter(Character characterToAdd)
{
lock (RequestMutex(characterToRemove.X, characterToRemove.Y))
{
loggedCharacters.Add(characterToAdd);
}
}
public Character[] GetCharacters(int x, int y)
{
lock (RequestMutex(characterToRemove.X, characterToRemove.Y))
{
foreach (var charact in loggedCharacters)
{
// exception here
}
}
}
// more methods that use the mutex when trying to remove/add/modify characters
}
Your problem is that you are locking the individual characters but not
loggedCharacters. You need to protectloggedCharacterswith a lock or make it a concurrent collection in order to avoid that exception.