예제 #1
0
        private Event WaitOnEvent()
        {
            MachineId mid = ActorModel.Runtime.GetCurrentMachineId();

            Console.WriteLine("Inside WaitOnEvent: " + mid);

            ActorModel.Runtime.Log($"<ActorModelLog> Machine '{mid.Name}' is " +
                                   "waiting to receive a result.");

            ActorModel.Runtime.SendEvent(this.ActorCompletionMachine,
                                         new ActorCompletionMachine.GetResultRequest(mid));

            Event resultEvent    = null;
            bool  receivedResult = false;

            while (!receivedResult)
            {
                resultEvent = ActorModel.Runtime.Receive(
                    Tuple.Create <Type, Func <Event, bool> >(typeof(ActorCompletionMachine.GetResultResponse), (Event e) =>
                {
                    if ((e as ActorCompletionMachine.GetResultResponse).Source.Equals(this.ActorCompletionMachine))
                    {
                        return(true);
                    }

                    return(false);
                }),

                    Tuple.Create <Type, Func <Event, bool> >(typeof(ActorMachine.ActorEvent), (Event e) =>
                {
                    if (ActorModel.Configuration.AllowReentrantCalls &&
                        ActorModel.ReentrantActors.ContainsKey(mid) &&
                        ActorModel.ReentrantActors[mid])
                    {
                        return(true);
                    }

                    ActorModel.Assert(!(e as ActorMachine.ActorEvent).ExecutionContext.Contains(mid),
                                      $"Deadlock detected. {mid.Name} is not reentrant.");

                    return(false);
                }));
                if (resultEvent is ActorCompletionMachine.GetResultResponse)
                {
                    receivedResult = true;
                }
                else
                {
                    var handler = ActorModel.GetReentrantActionHandler(mid);
                    handler(resultEvent as ActorMachine.ActorEvent);
                }
            }
            return(resultEvent);
        }