Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 子参与者在失败时不会重新启动_C#_.net_Akka_Console Application_Akka.net - Fatal编程技术网

C# 子参与者在失败时不会重新启动

C# 子参与者在失败时不会重新启动,c#,.net,akka,console-application,akka.net,C#,.net,Akka,Console Application,Akka.net,我有一位家长演员: public sealed class PersistenceSupervisor : ReceiveActor { protected override void PreStart() { base.PreStart(); Become(Active); } protected override SupervisorStrategy SupervisorStrategy() { r

我有一位家长演员:

public sealed class PersistenceSupervisor : ReceiveActor
{

    protected override void PreStart()
    {
        base.PreStart();

        Become(Active);
    }

    protected override SupervisorStrategy SupervisorStrategy()
    {
        return new OneForOneStrategy(
            10,
            TimeSpan.FromSeconds(0),
            x =>
            {
                return Directive.Restart;
            });
    }

    private void Active(object message)
    {
        IInventorPersister inventorPersistor = new InventorPersister();
        IActorRef persister = Context.ActorOf(Props.Create<Persister>(inventorPersistor), "persisterActor");
        var task = persister.Ask(message);
        task.Wait();
        Sender.Tell(task.Result);
    }
}

这个想法是重新启动子参与者,直到它成功。但是,当发生故障时,应用程序会立即停止并崩溃。谢谢你的帮助。非常感谢。

一些更一般的提示:

  • 您使用的是
    ReceiveActor
    ,它希望在actor的构造函数中通过
    Receive
    /
    ReceiveAsync
    方法提供消息处理程序
    Been(ActiveAsync)
    由非类型化的参与者而不是ReceiveActor继承者使用
  • 您是活动的异步方法,它不会返回一个任务,只返回一个纯空的任务——很难预测系统将如何运行,何时会从这种方法抛出异常
  • 不要在参与者的构造函数中使用
    been
    ,如果不需要,也不要使用
    PreStart
    方法。在actor初始化期间引发的异常将始终导致actor停止(即使it监管策略是重新启动它)
  • 也就是说,最简单的方法就是提供参与者will
    ReceiveAsync
    handler

    公共密封类持久器:ReceiveActor
    {
    私有只读inventorPersister inventorPersister;
    公共持久器(IIInventorPersister inventorPersister)
    {
    this.inventorPersister=inventorPersister;
    ReceiveAsync(异步消息=>
    {
    等待持续(消息);
    Context.Sender.Tell(“成功”);
    });
    }
    私有异步任务持久化(CreatePublication消息){…}
    ...
    }
    
    谢谢您的帮助,但我没有得到您的答案,因为我想故意抛出一个异常来测试主管策略。我不确定您为什么要测试它。大多数异常的主要原因是重新启动。您可以对其进行测试,但这样您就不会测试您的域,而是测试框架本身。我附上的代码显示了ReceiveActor的配置,因为我怀疑您初始化Actor的方式破坏了它们的内部结构。因为我想确保如果发生任何异常。子参与者将重新启动,直到成功从数据库获取数据。此外,异常不是来自构造函数,而是来自函数
    RandomFailure.Fail()
    。我已经尝试了你的代码,但它不起作用(引发异常并使应用程序崩溃)1。在无限循环中尝试从数据库获取数据是没有意义的,除非烧掉应用程序服务器。2.我展示的代码片段仍然允许您测试代码以进行演员重试,这是设计演员行为的实际方法。
    public sealed class Persister : ReceiveActor
    {
        private readonly IInventorPersister inventorPersister;
    
        protected override void PreStart()
        {
            base.PreStart();
    
            Become(ActiveAsync);
        }
    
        private async void ActiveAsync(object message)
        {
            try
            {
                var savedSender = Context.Sender;
                Task persisting = Persist(message as CreatePublication);
                await persisting;
                savedSender.Tell("Success");
            }
            catch (Exception e)
            {
                throw new Exception(e.ToString());
            }
        }
    
        public Persister(IInventorPersister inventorPersister)        
        {
            this.inventorPersister = inventorPersister;
        }
    
        private async Task Persist(CreatePublication message)
        {
            RandomFailure.Fail();    
            // This function is to make an UPDATE query to db        
            await inventorPersister.Persist(message.PublicationNumber, message.Inventors);            
        }
    
        // Random failure for testing purpose
        private static class RandomFailure
        {
            private static readonly Random R = new Random();
            public static void Fail()
            {
                if (R.Next(0, 2) == 0)
                {
                    throw new InvalidOperationException("Random failure");
                }
            }
        }
    }