lock(objectReference){}没有锁定临界区

时间:2012-10-12 21:49:37

标签: c# multithreading locking mutex

我有一个带有互斥锁的多维数组,我将它们用于一些关键部分。最后是我班上的素描。

现在,我尝试在不停止的情况下添加和删除不同线程中的字符,同时从另一个线程获取字符以测试我的服务器是否正常工作,但是当我尝试获取一个字符时,我得到一个例外这样说:“收集在foreach期间被修改了。”

任何人都知道为什么?我已经在MSDN中阅读了lock语句的文档,它应该可以工作,我不知道我做错了什么。也许new object[]不能用作互斥锁?

如果在这种情况下不应使用lock(objectReference),我应该使用什么呢?

我班上的草图:

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
}

1 个答案:

答案 0 :(得分:4)

您的问题是您要锁定单个字符,而不是loggedCharacters。您需要使用锁保护loggedCharacters或将其作为并发集合以避免该异常。