/// <summary>
 /// Runs the event.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <returns>The async task.</returns>
 private async Task StateEventRunner(StateMachineContextBase <TState, TTransition, TPayload> context)
 {
     try
     {
         await this.OnEnter(context);
     }
     catch (Exception ex)
     {
         if (null != this.faultHandler)
         {
             try
             {
                 this.faultHandler(context, ex);
             }
             catch (Exception newEx)
             {
                 this.stateMachine.FaultStateMachineContext(context, newEx);
             }
         }
         else
         {
             this.stateMachine.HandleFault(context, ex);
         }
     }
     finally
     {
         context.EndStateOperation();
     }
 }
        /// <summary>
        /// Handle a fault in the state machine.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="ex">The exception.</param>
        internal void HandleFault(StateMachineContextBase <TState, TTransition, TPayload> context, Exception ex)
        {
            if (StateMachineLifetime.Error == context.CurrentLifecycle)
            {
                return;
            }

            Exception faultReson = ex;

            if (this.faultHandler != null)
            {
                try
                {
                    // If this just succeeds. then continue.
                    this.faultHandler(context, ex);

                    return;
                }
                catch (Exception newEx)
                {
                    faultReson = newEx;
                }
            }

            this.FaultStateMachineContext(context, faultReson);
        }
 /// <summary>
 /// Remove the context.
 /// </summary>
 /// <param name="context">The context.</param>
 internal void RemoveContext(StateMachineContextBase <TState, TTransition, TPayload> context)
 {
     lock (this.contexts)
     {
         this.contexts.Remove(context);
     }
 }
        /// <summary>
        /// Begin invoking the transition on the context.
        /// </summary>
        /// <param name="transition">The transition.</param>
        /// <param name="context">The context.</param>
        public void InvokeTransition(TTransition transition, StateMachineContextBase <TState, TTransition, TPayload> context)
        {
            if (false == this.transitions.TryGetValue(transition, out var tranny))
            {
                throw new InvalidOperationException($"The transition {transition} from the state {this.State} does not exist.");
            }

            context.BeginTransition();

            // We are now transferring. Tranfer responsibility to the transition object.
            Task.Run(() => tranny.Execute(context));
        }
        /// <summary>
        /// Invokes the state entrance.
        /// </summary>
        /// <param name="context">The context.</param>
        public void InvokeEnter(StateMachineContextBase <TState, TTransition, TPayload> context)
        {
            context.BeginStateOperation();

            if (null != this.OnEnter)
            {
                Task.Run(() => this.StateEventRunner(context));
            }
            else
            {
                context.EndStateOperation();
            }
        }
Пример #6
0
        /// <summary>
        /// Execute the inter-transition interceptor.
        /// </summary>
        /// <param name="stateMachineContext">The state machine context.</param>
        /// <returns>An async task.</returns>
        internal async Task Execute(StateMachineContextBase <TState, TTransition, TPayload> stateMachineContext)
        {
            if (true == this.onTransitionDelegate.Any())
            {
                var context = StateMachineTransitionContext.Create(this.startState, this.endState.State, this.Message, this.stateMachine, stateMachineContext.Payload);
                await Task.WhenAll(this.onTransitionDelegate.Select(d => this.HandlerExecutor(d, context)));
            }

            if (StateMachineLifetime.Error == stateMachineContext.CurrentLifecycle)
            {
                return;
            }

            // We can continue on the same thread for the executing the next state.
            stateMachineContext.SetState(this.endState);

            // Fire of the state entrance.
            this.endState.InvokeEnter(stateMachineContext);
        }
 /// <summary>
 /// Fault the state machine context.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="ex">The exception.</param>
 internal void FaultStateMachineContext(StateMachineContextBase <TState, TTransition, TPayload> context, Exception ex)
 {
     this.RemoveContext(context);
     context.Fault();
 }