private static async Task <(bool, BackgroundTask)> QueueForExecutionAsync(this BackgroundTaskHost host,
                                                                                  Type type, object userData, Action <BackgroundTask> options)
        {
            var task = NewTask(host.Options, host.Serializer, type, userData);

            options?.Invoke(task);             // <-- at this stage, task should have a RunAt set by the user or it will be default

            if (!string.IsNullOrWhiteSpace(task.Expression) && !task.HasValidExpression)
            {
                throw new ArgumentException("The provided CRON expression is invalid.");
            }

            // Handle when no start time is provided up front
            if (task.RunAt == default)
            {
                task.RunAt = host.Store.GetTaskTimestamp();

                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 (host.Store != null)
            {
                await host.Store.SaveAsync(task);
            }

            if (!host.Options.DelayTasks)
            {
                return(await host.AttemptTaskAsync(task, false), task);
            }

            return(true, task);
        }
 /// <summary>
 ///     Schedules a new task for delayed execution for the given host.
 ///     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>
 /// <param name="host"></param>
 /// <param name="type"></param>
 /// <param name="userData"></param>
 /// <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>
 /// <returns>
 ///     Whether the scheduled operation was successful; 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 Task <(bool, BackgroundTask)> TryScheduleTaskAsync(this BackgroundTaskHost host, Type type,
                                                                  object userData = null, Action <BackgroundTask> options = null)
 {
     return(host.QueueForExecutionAsync(type, userData, options));
 }