2015-12-15 45 views
0

我正在構建一個井字遊戲api遊戲。遊戲工作正常,直到其中一名隊員在完成比賽的廣場上按下(他贏得勝利或填補棋盤)。Api控制器拋出一個異步相關異常

當我啓用了最後一步的所有CLR例外,這是我看到了線var user = await UserManager.FindByIdAsync(userId);

「其他信息除外:開始之前的異步操作完成之前這方面的一個第二次運行使用「。等待',以確保在調用此上下文中的另一個方法之前,任何異步操作都已完成。任何實例成員不保證是線程安全的。「

重要的是要知道玩家點擊廣場時,它是'POST'方法。 這裏是我的代碼:

public class GamesApiController : ApiController 
{ 
    ApplicationDbContext context = new ApplicationDbContext(); 

    private ApplicationUserManager _userManager; 

    public IEnumerable<ApplicationUser> Get() 
    { 
     return context.Users; 
    } 

    public ApplicationUserManager UserManager 
    { 
     get 
     { 
      return _userManager ?? System.Web.HttpContext.Current.Request.GetOwinContext().GetUserManager<ApplicationUserManager>(); 
     } 
     private set 
     { 
      _userManager = value; 
     } 
    } 

    #region Methods 
    /// <summary> 
    /// update the server data by reciving the model and square and returns the new model 
    /// </summary> 
    /// <param name="_model"></param> 
    /// <param name="squareId"></param> 
    /// <returns></returns> 

    //square clicked via post 
    [Route("api/gamesapi/{squareId}")] 
    public async Task<HttpResponseMessage> Post([FromBody]GameModel model, int squareId) 
    { 
     HttpResponseMessage response; 

     if (model == null) 
     { 
      //Utilites.CreateMsgCookie(Response, "Error", "Sorry, an unknown error has occurred"); 

      response = Request.CreateErrorResponse(HttpStatusCode.NotFound, "model wasn't found"); 

      return response; 
     } 

     //GameModel model = JsonConvert.DeserializeObject<GameModel>(_model); 

     Game game = GetGameById(model.Game.GameId); 

     if (game == null) 
     { 
      response = Request.CreateErrorResponse(HttpStatusCode.NotFound, "game wasn't found"); 
     } 
     else 
     { 
      if (game.UserIdTurn == game.User1Id) //pressing user is user1 
      { 
       ChangeSquareState(game, squareId, true); 
       game.UserIdTurn = game.User2Id; 
      } 
      else //game.UserIdTurn == game.User2Id - pressing user is user2 
      { 
       ChangeSquareState(game, squareId, false); 
       game.UserIdTurn = game.User1Id; 
      } 

      SquareState[] board = new SquareState[] {game.Square1,game.Square2,game.Square3,game.Square4, 
                 game.Square5,game.Square6,game.Square7,game.Square8,game.Square9}; 

      if (didPlayerWin(board)) 
      { 
       game.WinnerId = model.User.Id; 
       await UpdateUserGameState(1, game.User1Id); 
       await UpdateUserGameState(2, game.User2Id); 
       game.IsGameOver = true; 
      } 
      else 
      { 
       bool isBoardFull = true; 
       for (int i = 0; i < board.Length; i++) 
       { 
        if (board[i] == SquareState.Blank) 
        { 
         isBoardFull = false; 
         break; 
        } 
       } 
       if (isBoardFull) 
       { 
        await UpdateUserGameState(3, game.User1Id); 
        await UpdateUserGameState(3, game.User2Id); 
        game.IsGameOver = true; 
       } 
      } 

      context.SaveChanges(); 

      response = Request.CreateResponse(HttpStatusCode.OK, game); 
     } 
     return response; 
    } 

    /// <summary> 
    /// When a game is over, recive a gameState and update the user. 1 for a win, 2 for loss, 3 for aa draw 
    /// </summary> 
    /// <param name="gameState"></param> 
    private async Task UpdateUserGameState(int gameState, string userId) 
    { 
     var user = await UserManager.FindByIdAsync(userId); 
     switch (gameState) 
     { 
      case 1: 

       user.GamesWon++; 
       break; 

      case 2: 
       user.GamesLost++; 
       break; 

      case 3: 
       user.GamesDraw++; 
       break; 
      default: 
       break; 

     } 
     UserManager.UpdateAsync(user); 
    } 

    [HttpGet] 
    [Route("api/gamesapi/{gameId}")] 
    /// <summary> 
    /// method to bring the latest game's state from the context and send it back in a GameModel 
    /// </summary> 
    /// <param name="_model"></param> 
    /// <returns></returns> 
    public HttpResponseMessage Get(int gameId) 
    { 
     HttpResponseMessage response; 
     Game game = GetGameById(gameId); 

     if (game == null) 
     { 
      response = Request.CreateErrorResponse(HttpStatusCode.NotFound, "game wasn't found"); 
     } 
     else 
     { 
      response = Request.CreateResponse(HttpStatusCode.OK, game); 
     } 
     return response; 
    } 

    /// <summary> 
    /// method that check if the board have a line(3 squars in a row) 
    /// of the same element of user1 or user2 , defult - returns fault 
    /// </summary> 
    /// <param name="board"></param> 
    /// <returns></returns> 
    private bool didPlayerWin(SquareState[] board) 
    { 

    } 

    /// <summary> 
    /// change the SquareState of a specific square of the sent game according to the pressing user 
    /// </summary> 
    /// <param name="game"></param> 
    /// <param name="SquareId"></param> 
    /// <param name="_isUser1"></param> 

    private void ChangeSquareState(Game game, int SquareId, bool _isUser1) 
    { 

    } 

    /// <summary> 
    /// get game from context by gameId , Defult result - null 
    /// </summary> 
    /// <param name="gameId"></param> 
    /// <returns></returns> 
    private Game GetGameById(int gameId) 
    { 

    } 
    #endregion 
} 
+0

你需要等待'UserManager.UpdateAsync(用戶)'爲好。 – CodeCaster

+0

就是這樣,謝謝! –

回答

0

我想你錯過了方法UpdateUserGameState()等待UpdateUserAsync()

private async Task UpdateUserGameState(int gameState, string userId) 
{ 
    var user = await UserManager.FindByIdAsync(userId); 

    // ... 

    // add missing await 
    await UserManager.UpdateAsync(user); 
}