Orlens入门概念(2)创建Grains


建立

在编写代码以实现Grain类之前,在Visual Studio中创建一个新的针对.NET 4.6.1或更高版本的类库项目,并为其添加NuGet包。Microsoft.Orleans.OrleansCodeGenerator.Build

PM> Install-Package Microsoft.Orleans.OrleansCodeGenerator.Build

Grain接口和类

通过调用声明为相应Grain接口的一部分的方法,谷物相互交互并从外部调用一个Grain类实现了一个或多个先前声明的Grain接口。Grain接口的所有方法必须返回一个Task(对于void方法)或一个Task(对于返回类型值的方法T)。

以下是Presence服务示例的摘录

//an example of a Grain Interface
public interface IPlayerGrain : IGrainWithGuidKey
{
  Task GetCurrentGame();
  Task JoinGame(IGameGrain game);
  Task LeaveGame(IGameGrain game);
}

//an example of a Grain class implementing a Grain Interface
public class PlayerGrain : Grain, IPlayerGrain
{
    private IGameGrain currentGame;

    // Game the player is currently in. May be null.
    public Task GetCurrentGame()
    {
       return Task.FromResult(currentGame);
    }

    // Game grain calls this method to notify that the player has joined the game.
    public Task JoinGame(IGameGrain game)
    {
       currentGame = game;
       Console.WriteLine(
           "Player {0} joined game {1}", 
           this.GetPrimaryKey(),
           game.GetPrimaryKey());

       return Task.CompletedTask;
    }

   // Game grain calls this method to notify that the player has left the game.
   public Task LeaveGame(IGameGrain game)
   {
       currentGame = null;
       Console.WriteLine(
           "Player {0} left game {1}",
           this.GetPrimaryKey(),
           game.GetPrimaryKey());

       return Task.CompletedTask;
   }
}

从Grain方法返回值

Grain返回类型的值的方法T是在限定的Grain界面为返回一个Task对于Grain未用async关键字标记的方法,当返回值可用时,通常通过以下语句返回:

public Task GrainMethod1()
{
    ...
    return Task.FromResult();
}

Grain不返回值,有效的空隙的方法的方法,在一个被定义Grain的接口为返回Task返回Task值表示异步执行和方法的完成。对于Grain未用async关键字标记的方法,当“void”方法完成其执行时,它需要返回特殊值Task.CompletedTask

public Task GrainMethod2()
{
    ...
    return Task.CompletedTask;
}

Grain标记为方法async直接返回值:

public async Task GrainMethod3()
{
    ...
    return ;
}

一个Grain标记为“void”的方法async在执行结束时不会返回任何值。

public async Task GrainMethod4()
{
    ...
    return;
}

如果一个Grain方法接收到来自另一个异步方法调用的返回值Grain,并且不需要执行该调用的错误处理,则它可以简单地将Task它从该异步调用接收到的返回值作为其返回值:

public Task GrainMethod5()
{
    ...
    Task task = CallToAnotherGrain();
    return task;
}

同样,“void” Grain方法可以Task通过另一个调用返回给它,而不是等待它。

public Task GrainMethod6()
{
    ...
    Task task = CallToAsyncAPI();
    return task;
}

Grain参考

Grain参考是实现相同的代理对象Grain接口作为相应Grain类。它封装了目标的逻辑标识(类型和唯一键)Grain一个Grain基准就是用于制作到目标调用Grain每个Grain引用都是针对单个Grain(类的单个实例Grain),但可以为同一个引用创建多个独立引用Grain

由于Grain引用表示目标的逻辑身份Grain,因此它独立于该目标的物理位置Grain,并且即使在系统完全重新启动后仍保持有效。开发人员可以Grain使用其他.NET对象一样使用引用。它可以传递给一个方法,用作方法的返回值等等,甚至保存到持久存储中。

Grain参考可以通过传递的身份来获得GrainGrainFactory.GetGrain(key)方法,其中TGrain接口和key是的唯一密钥Grain的类型内。

以下是如何获取上面定义GrainIPlayerGrain接口引用的示例

Grain课堂内部

    //construct the grain reference of a specific player
    IPlayerGrain player = GrainFactory.GetGrain(playerId);

Orleans客户端代码。

在1.5.0之前:

    IPlayerGrain player = GrainClient.GrainFactory.GetGrain(playerId);

由于1.5.0:

    IPlayerGrain player = client.GetGrain(playerId);

Grain方法调用

Orleans编程模型是基于异步编程与异步和等待

使用Grain前面示例中参考,以下是执行Grain方法调用方法:

//Invoking a grain method asynchronously
Task joinGameTask = player.JoinGame(this);
//The await keyword effectively makes the remainder of the method execute asynchronously at a later point (upon completion of the Task being awaited) without blocking the thread.
await joinGameTask;
//The next line will execute later, after joinGameTask is completed.
players.Add(playerId);

有可能加入两个或更多Tasks连接操作会创建一个新的Task,当其所有组成Task部分完成时都会解析Grain需要启动多个计算并在继续之前等待所有计算完成时,这是一个有用的模式例如,Grain生成由多个部分组成的网页的前端可能会进行多个后端调用,每个部分一个,并Task为每个结果接收一个Grain随后将等待加入所有这些的Tasks当连接Task被解决时,个人Task已经完成,并且已经接收到格式化网页所需的所有数据。

例:

List tasks = new List();
Message notification = CreateNewMessage(text);

foreach (ISubscriber subscriber in subscribers)
{
   tasks.Add(subscriber.Notify(notification));
}

// WhenAll joins a collection of tasks, and returns a joined Task that will be resolved when all of the individual notification Tasks are resolved.
Task joinedTask = Task.WhenAll(tasks);
await joinedTask;

// Execution of the rest of the method will continue asynchronously after joinedTask is resolve.

虚拟方法

一个Grain类可以可选地覆盖OnActivateAsyncOnDeactivateAsync虚拟方法,这些方法Orleans在每个Grain类的激活和去激活时运行时调用这使Grain代码有机会执行额外的初始化和清理操作。OnActivateAsync激活过程失败引发的异常虽然OnActivateAsync如果被覆盖,总是作为Grain激活过程的一部分被调用,但OnDeactivateAsync不能保证在所有情况下被调用,例如,在服务器故障或其他异常事件的情况下。因此,应用程序不应该依赖OnDeactivateAsync来执行关键操作,例如状态更改的持久性,只能将其用于尽力而为的操作。

下一个

开发一个客户

你可能感兴趣的:(orleans)