c# - C# 如何处理字典项上的锁定?

标签 c# multithreading dictionary

我正在使用 C# (.NET 3.5) 为游戏编写一些寻路代码,我将寻路的并行性添加到游戏中以使其更快。 AI 代理必须向寻路系统“注册”并获得一个 id 作为返回。字典 agentMap 存储 AI 代理处理其寻路调用的信息(最后一个起点、终点和为最后一个寻路调用计算的路径)。

当我开始并行寻路搜索时,线程做的第一件事是调用 lock(agentMap[id])。问题是游戏循环在更新代理想要去的地方时也会访问 agentMap[id]。不知何故,游戏并没有卡住(据我所知)。

据我了解,agentMap[id] 锁定由键 id 引用的项目,因此当游戏循环尝试访问该项目时,游戏循环应该被封锁。是否有一些特殊的锁定字典项目的行为(或者我很幸运没有遇到问题)?

并行寻路线程的代码:

/*
    C# will nicely this function in a parallel thread for me
*/
void getBasicPathParallelized (object id)
{
    lock (agentMap [id]) {
        try {
            /* get path */
        } catch (Exception e) {
            /* error handling */
        }
    }
}

启动寻路线程:

agentMap [caller].pathfindingThread = new Thread (this.getBasicPathParallelized);
agentMap [caller].pathfindingThread.Start (caller);

操纵 agentMap [id] 项目的游戏循环代码太长,无法完整分享,但这里有一部分展示了游戏循环如何使用字典的项目:

agentMap [id].openList = new NodeList<PathNode> ();
agentMap [id].destination = destination;
agentMap [id].start = start;
agentMap [id].flags = flags;
++agentMap [id].pathSearchID;
agentMap [id].startTriangle = startTriangle;
agentMap [id].destinationTriangle = destinationTriangle;

最佳答案

so when the game loop tries to access that item the game loop should be blocked

没有。如果游戏循环试图锁定该项目,它将被阻止。如果它尝试访问该项目,那么它只会访问该项目。如果你想让它阻塞,它需要lock访问它。因为您在没有适当同步的情况下访问共享对象,所以可能会发生各种不好的事情。

请注意,像这样从多个地方改变一个对象,并让一个可广泛访问的对象同步,都是坏主意。这个对象几乎肯定是不可变的,并且对包含它的字典的更改应该通过负责确保正确同步访问的单一类型正确同步,可能通过使用 ConcurrentDictionary 而不是 Dictionary.

关于c# - C# 如何处理字典项上的锁定?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47338135/

相关文章:

c# - 在哪里为基于任务的异步方法定义回调

c++ - 从 vector 映射中查找并删除 std::function 对象

c++ - 反向映射值 c++

Python:优雅地将字典与值的 sum() 合并

c# - 我如何在 Vista 上设置 smtp 以便我可以使用 System.Net.Mail?

c# - 在没有类型库的情况下使用 C# 中的 COM dll

c# - DataGridView RowsAdded 事件处理程序不工作?

c++ - Qt单例实现

c - 如何判断两个线程是否访问了同一 block 内存?

multithreading - Grails,线程,自动服务