Search code examples
c#.net-coreactorakka.net

ReceiveActor Receive<T> in Akka.net is not working


im new to Akka.net, im running on linux and using .NET Core 3.1, i have written a very simple code but it does not work and i dont know why.

this my program.cs where i created the ActorSystem and simply called another actor

using Akka.Actor;

namespace PBFT
{
    class Program
    {
        static void Main(string[] args)
        {
            
            var MyActorSystem = ActorSystem.Create("ActorSystem");
            var Primary = MyActorSystem.ActorOf<PrimaryActor>();

            Primary.Tell("Test");
        }
    }
}

and this is the first actor that is supposed to receive the message and simply outputs it to the console

using Akka.Actor;
using Akka;
using Akka.Event;

namespace PBFT
{
    class PrimaryActor : ReceiveActor
    {
        private readonly ILoggingAdapter log = Context.GetLogger();
        public PrimaryActor()
        {
            Receive<string>(message => System.Console.WriteLine(message));
        }
    }
}

the problem is there are no errors and the message does not get processsed by the Actor, am i missing something ?


Solution

  • Messages to and between actors in Akka.NET are passed asynchronously. What happens in your example, is that you're Telling a message to an actor and exiting the program immediately afterwards, before actor got a chance to process the message.

    You can either suspend main thread (using eg. Console.ReadLine()) in your example, or - if you need to be sure that actor had processed the message before going forward - use combination of actor.Ask(message, cancellationToken) on the caller side (which will return Task, that completes once actor sends a response back) and Sender.Tell(response) inside your actor's receive method:

    class PrimaryActor : ReceiveActor
    {
        private readonly ILoggingAdapter log = Context.GetLogger();
        public PrimaryActor()
        {
            Receive<string>(message => {
                System.Console.WriteLine(message);
                Sender.Tell(new object()); // or any other response you want
            });
        }
    }
    
    class Program
    {
        static async Task Main(string[] args)
        {
            
            var MyActorSystem = ActorSystem.Create("ActorSystem");
            var Primary = MyActorSystem.ActorOf<PrimaryActor>();
    
            await Primary.Ask<object>("Test", default(CancellationToken));
        }
    }