Api控制器抛出异步相关的异常

时间:2015-12-15 12:15:29

标签: c# asynchronous asp.net-apicontroller

我正在构建一个Tic-Tac_toe api游戏。游戏工作正常,直到其中一个玩家按下一个完成游戏的广场(他赢了或填满了棋盘)。

当我为最后一次移动启用所有CLR例外时,这是我在第var user = await UserManager.FindByIdAsync(userId);行看到的例外

  

“附加信息:在上一个异步操作完成之前,在此上下文中启动了第二个操作。使用'await'确保在此上下文上调用另一个方法之前已完成任何异步操作。任何实例成员都不能保证是线程安全“。

重要知道玩家何时点击一个正方形,这是一个'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
}

1 个答案:

答案 0 :(得分:0)

我认为您错过了等待UpdateUserAsync()方法中的UpdateUserGameState()

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

    // ...

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