/// <summary> /// Declares a schedule placeholder that is stored with the state machine instance /// </summary> /// <typeparam name="TMessage">The scheduled message type</typeparam> /// <param name="propertyExpression">The schedule property on the state machine</param> /// <param name="tokenIdExpression">The property where the tokenId is stored</param> /// <param name="settings">The request settings (which can be read from configuration, etc.)</param> protected void Schedule <TMessage>(Expression <Func <Schedule <TInstance, TMessage> > > propertyExpression, Expression <Func <TInstance, Guid?> > tokenIdExpression, ScheduleSettings <TInstance, TMessage> settings) where TMessage : class { var property = propertyExpression.GetPropertyInfo(); var name = property.Name; var schedule = new StateMachineSchedule <TInstance, TMessage>(name, tokenIdExpression, settings); property.SetValue(this, schedule); Event(propertyExpression, x => x.Received); if (settings.Received == null) { Event(propertyExpression, x => x.AnyReceived); } else { Event(propertyExpression, x => x.AnyReceived, x => { settings.Received(x); }); } DuringAny( When(schedule.AnyReceived) .ThenAsync(async context => { Guid?tokenId = schedule.GetTokenId(context.Instance); ConsumeContext consumeContext; if (context.TryGetPayload(out consumeContext)) { Guid?messageTokenId = consumeContext.GetSchedulingTokenId(); if (messageTokenId.HasValue) { if (!tokenId.HasValue || (messageTokenId.Value != tokenId.Value)) { if (_log.IsDebugEnabled) { _log.DebugFormat("SAGA: {0} Scheduled message not current: {1}", context.Instance.CorrelationId, messageTokenId.Value); } return; } } } BehaviorContext <TInstance, TMessage> eventContext = context.GetProxy(schedule.Received, context.Data); await((StateMachine <TInstance>) this).RaiseEvent(eventContext).ConfigureAwait(false); schedule.SetTokenId(context.Instance, default(Guid?)); })); }