/// <summary>
        /// Ensures workflow timers are registered for waking the instance up.
        /// </summary>
        /// <returns></returns>
        async Task SaveReminderAsync()
        {
            // next date at which the reminder should be invoked
            var dueDate = (DateTime?)state.GetInstanceData(ActivityTimerExpirationTimeKey) ?? DateTime.MinValue;

            if (dueDate != DateTime.MinValue)
            {
                // lock down current time
                var nowDate = DateTime.UtcNow;

                // don't allow dates in the past
                if (dueDate < nowDate)
                {
                    dueDate = nowDate;
                }

                // unregister reminder if it the time has changed
                var reminder = actor.TryGetReminder(ActivityTimerExpirationReminderName);
                if (reminder != null)
                {
                    // deserialize last due date from reminder
                    var lastDueDate = DateTime.FromBinary(BitConverter.ToInt64(reminder.State, 0));
                    if (lastDueDate != dueDate)
                    {
                        // timer is out of range, will reschedule below
                        await actor.UnregisterReminderAsync(reminder);

                        reminder = null;
                    }
                }

                // schedule new reminder
                if (reminder == null)
                {
                    await actor.RegisterReminderAsync(
                        ActivityTimerExpirationReminderName,
                        BitConverter.GetBytes(dueDate.ToBinary()),
                        (dueDate - nowDate).Max(TimeSpan.FromMilliseconds(100)),
                        TimeSpan.FromMilliseconds(-1));
                }
            }
            else
            {
                // no reminder required, unregister existing reminder
                var reminder = actor.TryGetReminder(ActivityTimerExpirationReminderName);
                if (reminder != null)
                {
                    await actor.UnregisterReminderAsync(reminder);
                }
            }
        }
Esempio n. 2
0
 /// <summary>
 /// Loads the instance data for the given instance ID.
 /// </summary>
 /// <param name="instanceId"></param>
 /// <returns></returns>
 IDictionary <XName, InstanceValue> LoadInstanceData(Guid instanceId)
 {
     return(state.GetInstanceDataNames().ToDictionary(i => (XName)i, i => new InstanceValue(FromSerializableObject(state.GetInstanceData(i)))));
 }