2

I created singleton wrapper over ActorSystem

using System;
using System.IO;
using System.Linq;
using System.Threading;
using System.Xml.Linq;

using Akka.Actor;
using Akka.Configuration;

namespace AkkaPOC
{
    public sealed class ActorsDirector : IDisposable
    {    
        private static readonly Lazy<ActorsDirector> instance =
            new Lazy<ActorsDirector>(() =>
                new ActorsDirector(),
                LazyThreadSafetyMode.ExecutionAndPublication);

        public static ActorSystem Instance
            => instance.Value.director;

        private readonly ActorSystem director;

        private ActorsDirector()
        {
            var config  = ConfigurationFactory.ParseString(
                XElement.Parse(File.ReadAllText(@$"{Directory.GetCurrentDirectory()}\akka.config"))
                        .Descendants("hocon")
                        .Single()
                        .Value);

            this.director = ActorSystem.Create("ActorDirector", config);
        }

        bool isDisposed = false;

        ~ActorsDirector()
        {
            Dispose(false);
        }

        /// <inheritdoc/>
        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

        private void Dispose(bool disposing)
        {
            if (this.isDisposed)
                return;
            if (disposing)
            {
                this.director.Dispose();
            }

            this.isDisposed = true;
        }
    }
}

And when I use it from synchronously code all is fine! But when Actor's are created in parallel Task's

for (int i = 0; i < 20; i++)
{
    new Task(() =>
    {
        var actor = ActorsDirector.Instance
                                    .ActorOf<AskerActor>()
                                    .Ask<T>(parameters)
        actor.Wait();
        Console.WriteLine("uint: {0}", actor.Result);
    }).Start();
}

project stops in wrapper's ctor after

this.director = ActorSystem.Create("ActorDirector", config);

and doesn`t work further.

Which is interesting, if in the cycle we make a restriction not of 20, but not more than 8, then with some delay everything will work.

Can someone say me what I do incorrect and how to fix it.

EgoPingvina
  • 734
  • 1
  • 10
  • 33
  • Hello, i have noticed some problem in your code but i'm not quite sure that it's the problem. You don't have any static reference at actor system variable at global application level as it recommended by documentation. All your references are local inside lambda and after task completion GC can delete actor system object. Can you create reference at actor system at application root level and try again? – Sergey Popov Dec 24 '19 at 20:28
  • @SergeyPopov, I added `public static ActorSystem system = ActorsDirector.Instance;` above `Main`- nothing is changed – EgoPingvina Dec 25 '19 at 09:25
  • Ok, can you show me the full sources? – Sergey Popov Dec 25 '19 at 10:19

0 Answers0