C#C
C#3y ago
Turwaith

❔ Akka.net Actors are not responding in time

I have a system that consists of two Actor classes and a class that calls these actors.
public class ActorsystemManager
{
    readonly ActorSystem simulationActorSystem;
    readonly IActorRef updateActorRef;
    private List<ActorState> currentActorStates = new();

    private readonly object locker = new();

    public int ActorChangeInterval { get; set; }

    // This property is accessed by both this class to write and by the interface to read. Always use "lock" when accessing it!
    public List<ActorState> CurrentActorStates 
    {
        get
        {
            lock (locker)
            {
                return currentActorStates; 
            }
        }
        set 
        {
            lock (locker)
            {
                currentActorStates = value;  
            }
        }
    }

    public ActorsystemManager(int actorChangeInterval, List<int[]> coordinates)
    {
        ActorChangeInterval = actorChangeInterval;

        simulationActorSystem = ActorSystem.Create("SimulationActorSystem");
        updateActorRef = simulationActorSystem.ActorOf(Props.Create<UpdateActor>(actorChangeInterval, coordinates), "UpdateActor");

        UpdateTimer timer = new UpdateTimer();
        timer.Elapsed += OnTimerTick;
    }

    private void OnTimerTick(object sender, EventArgs e)
    {
        updateActorRef.Ask<List<ActorState>>("update")
            .ContinueWith(task =>
            {
                if (task.IsCompletedSuccessfully)
                {
                    UpdateCurrentActorStates(task.Result);
                }
                // Handle other cases, like task.IsFaulted or task.IsCanceled, if needed
            }, TaskScheduler.Default);
    }

    private void UpdateCurrentActorStates(List<ActorState> result)
    {
        CurrentActorStates = new List<ActorState>(result);
    }

    public void Trigger(int[] coordinates)
    {
        updateActorRef.Tell(coordinates);
    }

    public bool Dispose()
    {
        try
        {
            simulationActorSystem.Dispose();
            return true;
        }
        catch (Exception)
        {

            return false;
        }
    }
}

Actors:
internal class UpdateActor : ReceiveActor
{
    public List<IActorRef> HexagonActors { get; set; }

    public UpdateActor()
    {
        HexagonActors = new List<IActorRef>();

        ReceiveAsync<string>(data => data.ToLower().Equals("update"), async data => await Update());

        Receive<int[]>(data => Trigger(data));
    }

    public UpdateActor(int actorChangeInterval, List<int[]> coordinates) : this()
    {
        foreach (var item in coordinates)
        {
            string coordinatesText = $"{item[0]}_{item[1]}";
            var child = Context.ActorOf(Props.Create<HexagonActor>(actorChangeInterval, item), coordinatesText);
            HexagonActors.Add(child);
        }
    }

    private async Task Update()
    {
        var actorStates = new List<ActorState>();

        foreach (var actor in HexagonActors)
        {
            try
            {
                var actorState = await actor.Ask<ActorState>("update", TimeSpan.FromMilliseconds(200));
                actorStates.Add(actorState);
            }
            catch (AskTimeoutException ex)
            {                    
                throw new AskTimeoutException("");
            }
        }

        Sender.Tell(actorStates);
    }

    private void Trigger(int[] coordinates)
    {
        var coordinateAddress = $"{coordinates[0]}_{coordinates[1]}";
        Context.ActorSelection("akka://SimulationActorSystem/user/UpdateActor/" + coordinateAddress).Tell("trigger");
    }
}

2nd actor and problem follows in a second message, hang on
Was this page helpful?