【问题标题】:How to reduce code duplication for ReceiveActor如何减少 ReceiveActor 的代码重复
【发布时间】:2016-11-11 08:06:52
【问题描述】:

我有具有可切换行为的接收 Actor,由 become() 方法切换。为了监控子演员,我必须在每个状态方法中添加 Receive 调用。

例如,我必须将其粘贴到 Ready、Working1 和 Working2 方法中

public class SomeActor : ReceiveActor
{
    public SomeActor()
    {
        // create child actors
        Become(Ready);
    }

    private void Ready()
    {
        Receive<InitMessage>(m =>
        {
            Become(Working1);
        });

        Receive<Terminated>(m =>
        {
            // duplicated termination stuff 
            Become(Terminated);
        });
    }

    private void Working1()
    {
        Receive<InitMessage>(m =>
        {
            Become(Working2);
        });

        Receive<Terminated>(m =>
        {
            // duplicated termination stuff 
            Become(Terminated);
        });
    }

    private void Working2()
    {
        Receive<InitParcerMessage>(m =>
        {
            Become(Working1);
        });

        Receive<Terminated>(m =>
        {
            // duplicated termination stuff 
            Become(Terminated);
        });
    }

    private void Terminated()
    {
        // do some stuff
    }
}

【问题讨论】:

  • 很难理解您真正想要达到的目标。在 akka 监视/监视中,演员是一个与使用 Context.Watch(actorRef) 检查其活跃度相关的术语。请在此处描述您真正想要监控的内容。
  • 您可以触发一个事件并为所有子级订阅它,让他们知道您何时要在成为结束时处理 Terminated 方法,在某个中间点等
  • @Zinov 你的意思是简单的 c# 事件?
  • 是的@bonzaster 它也应该以这种方式工作,最后事件是委托类型,因此您可以拨打电话

标签: c# .net akka akka.net


【解决方案1】:

您正在使用 lambda 来执行您的操作,相反,您可以创建一个私有方法,将 Terminated 类型作为参数并在您的 Receive 操作中使用 MethodGroup

public class SomeActor : ReceiveActor
{
    public SomeActor()
    {
        // create child actors
        Become(Ready);
    }

    private void Ready()
    {
        Receive<InitMessage>(m =>
        {
            Become(Working1);
        });

        ConfigureReceive();
    }

    private void Working1()
    {
        Receive<InitMessage>(m =>
        {
            Become(Working2);
        });

        ConfigureReceive();
    }

    private void Working2()
    {
        Receive<InitParcerMessage>(m =>
        {
            Become(Working1);
        });

        ConfigureReceive();
    }

    private void Terminated()
    {
        // do some stuff
    }

    private void ConfigureReceive()
    {
        // Register Receive actors here
        Receive<Terminated>(p => HandleTermination(p));
    }

    // Here's our method to perform the same job with our Terminated parameter
    private void HandleTermination(Terminated termination)
    {
        // Call our Become method
        Become(Terminated);
    }
}

【讨论】:

  • 同意,但无论如何我必须在任何地方添加这个 Receive(HandleTermination); 。试想一下,如果我想以这种方式处理不止一种消息类型,那么重复的行会更多
  • 我已经更新了代码 sn-p。您必须在某处进行一些代码重复,但此更新将其精简以将您的 Receive 保留在一种方法中,因此您只需在一个地方更新代码。
  • 谢谢,好像是答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多