Akka.net等待多条数据

Akka.net waiting for multiple pieces of data

这是我 运行 遇到的一个常见场景,其中我有两个(或更多)演员异步获取一些数据,然后我需要在他们全部完成后执行操作。

执行此操作的常见模式是什么?

这是一个简化的例子。

public MasterActor : ReceiveActor
{
     public MasterActor() 
     {
          Initialize();
     }

     public void Initiaize()
     {
         Receive<DoSomeWork>(_ => 
         {
              var actor1 = Context.ActorOf(Props.Create(() => new Actor1());
              var actor2 = Context.ActorOf(Props.Create(() => new Actor2());

              // pretend these actors send responses to their senders
              // for sake of example each of these methods take between 1 and 3 seconds
              actor1.Tell(new GetActor1Data());
              actor2.Tell(new GetActor2Data());
         });

        Receive<Actor1Response>(m => 
        {
             //actor 1 has finished it's work
        });

        Receive<Actor2Response>(m => 
        {
             //actor 2 has finished it's work
        });
     }
}

为了开始这个,我向 MasterActor 发送了一条 DoSomeWork 消息。

当我同时拥有 Actor1ResponseActor2Response 时,执行操作的常用方法是什么?

我真的不想在每个接收处理程序中都有逻辑来检查另一个接收处理程序是否完成或类似的事情。我猜我在想什么类似于 Task.WaitAll() 方法。

我只是以错误的方式解决问题吗?我需要用不同的方式重写演员吗?

任何常见的模式或解决方案都会很棒。

常见的解决方案是附加某种由请求和响应消息共享的相关 ID - 因为 actor 同步处理消息,所以这可能是未选中的 int/long 计数器。

您只需将关联 ID 存储在调用方内部的某个数据结构(比如说集合)中,并在收到响应时从集合中删除它的关联 ID。 WaitAll set为空或超时时基本完成。

你可以使用Context.SetReceiveTimeout(timeout)设置超时,这样actor会在一段时间没有收到任何消息后向自己发送一个ReceiveTimeout方法。

此行为非常通用,可以很容易地抽象出来。

最简单的方法是在每个 child 回复时增加主服务器上的 "vote" 计数。当投票 == child 计数时,您就完成了。

您可以扩展它,以便只计算来自每个 child 的第一条消息,或者来自每个 child 的特定消息,但最终都归结为计数。