private static bool QueueForExecution <T>(this ScheduledProducer producer, Action <ScheduledTask> options, object instance) { var task = NewTask <T>(producer.Settings, instance); options?.Invoke(task); // <-- at this stage, task should have a RunAt set by the user or it will be default // Validate the CRON expression: if (!string.IsNullOrWhiteSpace(task.Expression) && !task.HasValidExpression) { throw new ArgumentException("The provided CRON expression is invalid. Have you tried the CronTemplates?"); } // Handle when no start time is provided up front if (task.RunAt == default(DateTimeOffset)) { task.RunAt = DateTimeOffset.UtcNow; if (task.NextOccurrence.HasValue) { task.RunAt = task.NextOccurrence.Value; } } // Set the "Start" property only once, equal to the very first RunAt task.Start = task.RunAt; if (!producer.Settings.DelayTasks) { return(producer.AttemptTask(task, false)); } producer.Settings.Store?.Save(task); return(true); }
/// <summary> /// Schedules a new task for delayed execution for the given producer. /// /// If the user does NOT provide a RunAt during options, but an expression IS provided, the next occurrence of the expression, relative to now, will be selected as the start time. /// Otherwise, the task will be scheduled for now. /// /// </summary> /// <typeparam name="T">The type of the task. The task is created at trigger time. The trigger type must have a parameterless constructor.</typeparam> /// <param name="options">Allows configuring task-specific features. Note that this is NOT invoked at invocation time lazily, but at scheduling time (i.e. immediately). </param> /// <param name="configure">Allows setting parameters on the scheduled task. Note that this is NOT invoked at invocation time lazily, but at scheduling time (i.e. immediately).</param> /// <returns>Whether the scheduled operation was successfull; if `true`, it was either scheduled or ran successfully, depending on configuration. If `false`, it either failed to schedule or failed during execution, depending on configuration.</returns> public static bool ScheduleAsync <T>(this ScheduledProducer producer, Action <ScheduledTask> options = null, Action <T> configure = null) where T : class, new() { T instance = null; if (configure != null) { instance = (T)Activator.CreateInstance(typeof(T)); configure(instance); } return(QueueForExecution <T>(producer, options, instance)); }