I have a ConcurrentDictionary stoing Items:
ConcurrentDictionary<ulong, Item> items;
Now I would like to lock on an Item from this dictionary so I may safely operate on it.
Is this code correct?
try
{
    Item item;
    lock(item = items[itemId])
    {
        // do stuff
        // possibly remove itemId from the dictionary
    }
}
catch(KeyNotFoundException)
{
    // ...
}
My fear is this. I suppose lock(item = items[itemId]) can be decomposed into two operations:
- Assign reference of 
items[itemId]toitem - Lock on 
item 
Which are not necessarily atomic.
So, I'm fearing the following race condition:
- Thread 1 performs 
item = items[itemId], but doesn't yet performlock(item) - Thread 2 performs 
lock(item = items[itemId])for the same value ofitemId - Thread 2 erases 
itemIdfromitems - Thread 2 releases its lock
 - Thread 1 performs 
lock(item), not knowingitemIdis no longer in the dictionary - Thread 1 incorrectly operates on 
item, instead of going to itscatchblock, as it should. 
Is the above analysis correct?
In that case, would it be sufficient to modify my code this way?
try
{
    Item item;
    lock(items[itemId])
    {
        item = items[itemId];
        // do stuff
        // possibly remove itemId from the dictionary
    }
}
catch(KeyNotFoundException)
{
    // ...
}
EDIT: Because I'm starting to suppose I've fallen for the XY problem. Here's the background.
Multiplayer chess game. itemId is the game's ID. item is the game's current state. The dict holds ongoing items. The operation is to process a player's move, like "knight from e3 goes to d1". If because of a player's move the game completes, then we return the final state of the game and remove the game from the dictionary. It is, of course, invalid to perform any further moves on a completed game, hence the try/catch block.
The try/catch block is supposed to correctly detect the following situations:
- a player sends an invalid command, ordering to make a move in a non-existent game;
 - Because of network lag, a players command to make a move on a valid game arrives to the server after their timer run out.