Dev243
Dev243

Reputation: 53

How Does C# Handle Locking On A Dictionary Item?

I was working on some pathfinding code for a game in C# (.NET 3.5) and I added parallelism of the pathfinding to the game to make it faster. The AI agents must "register" with the pathfinding system and are provided a id in return. A dictionary agentMap stores information for a AI agent to do with it's pathfinding calls (the last start point, end point and path calculated for the last pathfinding call).

When I start a parallel pathfinding search the first thing the thread does is call lock(agentMap[id]). The thing is that the game loop also accesses agentMap[id] when updating where the agent wants to go. Somehow, the game hasn't frozen up (as far as I can tell).

As I understand it, agentMap[id] locks on the item referred to by the key id so when the game loop tries to access that item the game loop should be blocked. Is there some special behaviour of locking on a dictionary item (or am I just lucky not to have problems)?

Code for parallel pathfinding thread:

/*
    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 */
        }
    }
}

Starting the pathfinding thread:

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

The game loop code that manipulates the agentMap [id] items is too long to share in full but here is a section to show how the game loop uses the items of the dictionary:

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;

Upvotes: 1

Views: 233

Answers (1)

Servy
Servy

Reputation: 203809

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

No. If the game loop tries to lock on the item, it'll be blocked. If it tries to access the item then it will just access the item. If you want it to block, it needs to lock around access to it. Because you're accessing a shared object without proper synchronization, all sorts of bad things can happen.

Note that mutating an object from multiple places like this, and having a widely accessible object being synchronized on, are both bad ideas. This object should almost certainly be immutable, and changes to the dictionary holding it should be properly synchronized through a single type responsible for ensuring properly synchronized access, possibly by using a ConcurrentDictionary instead of a Dictionary.

Upvotes: 3

Related Questions