加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

在Microsoft Orleans中检查GUID是否存在颗粒

发布时间:2020-12-14 05:45:29 所属栏目:Windows 来源:网络整理
导读:如何检查特定Id的颗粒是否已存在? 考虑到下面将创建一个新的播放器粒度与Id我传入GetGrain()如果它不存在,我不知道如何检查是否已经存在. public async TaskGuid Create(Guid playerGuid) { var player = GrainClient.GrainFactory.GetGrainIPlayerGrain(pl
如何检查特定Id的颗粒是否已存在?

考虑到下面将创建一个新的播放器粒度与Id我传入GetGrain()如果它不存在,我不知道如何检查是否已经存在.

public async Task<Guid> Create(Guid playerGuid)
    {
        var player = GrainClient.GrainFactory.GetGrain<IPlayerGrain>(playerGuid);
        var gameGuid = await player.CreateGame();

        return gameGuid;
    }

解决方法

简短的回答是存储一些状态,以便谷物知道它是否先前已被激活.

奥尔良的谷物永远不会被明确地创建或销毁:它们始终可用于处理请求.因此,从技术上讲,谷物是否存在的概念并不适用于奥尔良.另一方面,我们可以问“有这个id的颗粒曾被激活过”.

您可能需要检查两种情况:

>谷物从未被激活过,但你期待它已经被激活了.例如:我在IPlayerGrain上调用一个方法,但播放器不存在.
>谷物之前已被激活,但你期望它没有.例如:我正在尝试为这个玩家创建一个新游戏,但该游戏已被采用.

在下面的代码示例中,您可以看到两种情况:

>如果之前从未创建过播放器,则对IPlayerGrain.CreateGame()的调用将抛出异常.忽略我永远不会设置Created的事实,可以在一些CreatePlayer(…)方法中完成.
>如果游戏已经创建,对IGameGrain.TryCreateGame(播放器)的调用将返回false.在这种情况下,IPlayerGrain.CreateGame()将继续循环,直到找到一个尚未创建的游戏.有了Guid id,你就不太可能看到碰撞了,但我明白了要谨慎的愿望 – 只要让星星对齐并对你不利.

public interface IPlayerGrain : IGrainWithGuidKey
{
    Task<Guid> CreateGame();
}

public class PlayerState
{
    public bool Created { get; set; }
}

public class PlayerGrain : Grain<PlayerState>,IPlayerGrain
{
    public async Task<Guid> CreateGame()
    {
        if (!this.State.Created)
          throw new InvalidOperationException("Player does not exist.");

        var thisPlayer = this.AsReference<IPlayerGrain>();

        var created = false;
        var gameId = default(Guid);
        while (!created)
        {
            // Get a new,random game grain
            gameId = Guid.NewGuid();

            // Try to create a game.
            created = await this.GrainFactory.GetGrain<IGameGrain>(gameId)
                                .TryCreateGame(thisPlayer);

            // If the game was successfully created,break out and return the id.
            // Otherwise,keep looping.
        }

        return gameId;
    }
}
public interface IGameGrain : IGrainWithGuidKey
{
    // Returns true if game was created,false otherwise.
    Task<bool> TryCreateGame(IPlayerGrain player);
}

public class GameState
{
    public IPlayerGrain Player { get; set; }
}

public class GameGrain : Grain<GameState>,IGameGrain
{
    public async Task<bool> TryCreateGame(IPlayerGrain player)
    {
        // If this grain already has a player,return false.
        if (this.State.Player != null) return false;

        // Otherwise,set the player,write it to storage,and return true.
        this.State.Player = player;
        await this.WriteStateAsync();
        return true;
    }
}

您问题中的Create方法无需更改.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读