public async Task <BodyResponse <MoneyMqResponse> > Handle(BuyInCommand request, CancellationToken cancellationToken) { using (var locker = _redis.Locker(KeyGenHelper.GenUserKey(request.Id, MoneyInfo.ClassName))) { await locker.LockAsync(); var moneyInfo = await _redis.GetMoney(request.Id); if (moneyInfo == null) { moneyInfo = await _moneyRepository.FindAndAdd(request.Id, new MoneyInfo(request.Id, 0, 0, 0, 0, 0)); } if (moneyInfo.CurCoins + moneyInfo.Carry < request.MinBuy) { return(new BodyResponse <MoneyMqResponse> (StatusCodeDefines.NoEnoughMoney, null, null)); } long realBuy = 0; if (moneyInfo.CurCoins + moneyInfo.Carry >= request.MaxBuy) { realBuy = request.MaxBuy; } else { realBuy = moneyInfo.CurCoins + moneyInfo.Carry; } long left = moneyInfo.Carry - realBuy; if (left < 0) { moneyInfo.AddCoins(left); moneyInfo.AddCarry(realBuy); } var moneyevent = new MoneyChangedMqEvent (moneyInfo.Id, moneyInfo.CurCoins, moneyInfo.CurDiamonds, moneyInfo.MaxCoins, moneyInfo.MaxDiamonds, 0, 0); _busCtl.PublishExt(moneyevent); await Task.WhenAll(_redis.SetMoney(request.Id, moneyInfo), _moneyRepository.ReplaceAsync(moneyInfo)); return(new BodyResponse <MoneyMqResponse>(StatusCodeDefines.Success, null, new MoneyMqResponse(request.Id, moneyInfo.CurCoins, moneyInfo.CurDiamonds, moneyInfo.MaxCoins, moneyInfo.MaxDiamonds, moneyInfo.Carry))); } }