Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Having problem making my code thread-safe

CreateNewRound() method is accessed by multiple threads at runtime. Let's say the _game.CurrentRound = 99 and two threads access the method at the same time and they both initialize the currentRoundId as 100 and both threads add two entities with the same roundId. But that is wrong and I don't want that to happen since rounds should be unique and different. How can I fix this so that thread one adds an entity with round 100 and the other with round 101.


public void CreateNewRound()
{
   var game = _cache.GetGameById(_session.gameId);
   var currentRoundId = game.CurrentRound + 1;

   var response = SomeAPI.SomeCall();
   if (response.responseCode == (int)responseCodes.Success)
   { 
      _dbContext.GameState.Add(new GameState() { RoundId = CurrentRoundId });
      _dbContext.SaveChanges();
   }
}
like image 971
Artavazd Avatar asked Dec 19 '25 08:12

Artavazd


1 Answers

If (and only if) all called methods are pure, i.e. where the result only depends on the input parameters, you can simply used interlocked.Increment to ensure the currentRound will be unique for each call:

    private int currentRound = 0;
    public void CreateNewRound()
    {
        var thisRound = Interlocked.Increment(ref currentRound);
        var gamestate = CreateGameState(thisRound)
        // process game state
    }

In most games, the next round will depend on the game-state of the previous round. And in that case you must run each round sequentially. The typical solution would be to use a lock for this:

    private int currentRound = 0;
    private object myLock = new object();
    private MyGameState gameState;
    public void CreateNewRound()
    {
        lock (myLock)
        {
            currentRound++;
            gameState = ComputeNextGameState(gameState, currentRound);
            // process game state
        }
     }

There are alternatives, like assigning a specific thread to do all game-state updates, and make CreateNewRound merely ask the update thread to do an update.

like image 97
JonasH Avatar answered Dec 20 '25 20:12

JonasH



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!