public async Task <int> SaveTask(ScheduleTaskDTO req)
        {
            AssertUtils.IsNotEmpty(req.TaskName, $"{nameof(AixScheduleTaskInfo.TaskName)}为空");
            AssertUtils.IsNotEmpty(req.Cron, $"{nameof(AixScheduleTaskInfo.Cron)}为空");
            AssertUtils.IsNotEmpty(req.TaskContent, $"{nameof(AixScheduleTaskInfo.TaskContent)}为空");
            AssertUtils.IsTrue(req.MaxRetryCount >= 0, $"{nameof(AixScheduleTaskInfo.MaxRetryCount)} 为空");

            var model = await _aixScheduleTaskRepository.GetById(req.TaskId);

            if (model == null)
            {
                model = new AixScheduleTaskInfo
                {
                    TaskGroup       = req.TaskGroup ?? "",
                    TaskStatus      = 1,
                    TaskName        = req.TaskName,
                    TaskDesc        = req.TaskDesc ?? "",
                    Cron            = req.Cron,
                    TaskContent     = req.TaskContent ?? "",
                    LastExecuteTime = 0,
                    NextExecuteTime = 0,
                    MaxRetryCount   = req.MaxRetryCount,
                    CreatorId       = req.UserId ?? "",
                    CreateTime      = DateTime.Now,
                    ModifierId      = req.UserId ?? "",
                    ModifyTime      = DateTime.Now
                };

                var newId = await _aixScheduleTaskRepository.InsertAsync(model);

                model.Id = (int)newId;
            }

            else
            {
                model = new AixScheduleTaskInfo
                {
                    Id        = req.TaskId,
                    TaskGroup = req.TaskGroup ?? "",
                    //TaskStatus = 1,
                    TaskName    = req.TaskName,
                    TaskDesc    = req.TaskDesc ?? "",
                    Cron        = req.Cron,
                    TaskContent = req.TaskContent ?? "",
                    // LastExecuteTime = 0,
                    // NextExecuteTime = 0,
                    MaxRetryCount = req.MaxRetryCount,
                    // CreatorId = req.UserId ?? "",
                    // CreateTime = DateTime.Now,
                    ModifierId = req.UserId ?? "",
                    ModifyTime = DateTime.Now
                };
                await _aixScheduleTaskRepository.UpdateAsync(model);
            }
            return(model.Id);
        }
        private async Task <List <TimeSpan> > Execute()
        {
            List <TimeSpan> nextExecuteDelays = new List <TimeSpan>(); //记录每个任务的下次执行时间,取最小的等待

            if (_taskExecutor.GetTaskCount() > _options.Backlog)
            {
                _logger.LogWarning($"Aix.ScheduleTask定时任务积压太多超过{_options.Backlog}条定时任务待处理");
                await Task.Delay(TimeSpan.FromSeconds(5));

                return(nextExecuteDelays);
            }

            var now      = DateTimeUtils.GetTimeStamp();
            var taskList = await _aixScheduleTaskRepository.QueryAllEnabled(PreReadSecond * 1000 + now); //拉取即将到期的任务 提前{PreReadSecond}秒

            //逐个处理
            foreach (var task in taskList)
            {
                _scheduleTaskLifetime.ScheduleTaskStopping.ThrowIfCancellationRequested();

                var Schedule = CrontabHelper.ParseCron(_logger, task);
                if (task.LastExecuteTime == 0)
                {
                    task.LastExecuteTime = now;                            //任务第一次执行时,从当前时间开始
                }
                var nextExecuteTimeSpan = CrontabHelper.GetNextDueTime(Schedule, DateTimeUtils.TimeStampToDateTime(task.LastExecuteTime), DateTimeUtils.TimeStampToDateTime(now));

                if (nextExecuteTimeSpan <= TimeSpan.Zero)                               //时间到了,开始执行任务
                {
                    if (nextExecuteTimeSpan >= TimeSpan.FromSeconds(0 - PreReadSecond)) //排除过期太久的,(服务停了好久,再启动这些就不执行了)
                    {
                        await _scheduleTaskExecutor.Trigger(task, TimeSpan.Zero);       //
                    }

                    now = DateTimeUtils.GetTimeStamp();
                    task.LastExecuteTime = now;
                    //计算下一次执行时间
                    nextExecuteTimeSpan  = CrontabHelper.GetNextDueTime(Schedule, DateTimeUtils.TimeStampToDateTime(task.LastExecuteTime), DateTimeUtils.TimeStampToDateTime(now));
                    task.NextExecuteTime = now + (long)nextExecuteTimeSpan.TotalMilliseconds;
                    task.ModifyTime      = DateTime.Now;
                    await _aixScheduleTaskRepository.UpdateAsync(task);
                }

                if (task.NextExecuteTime == 0)  //只有第一次且未执行时更新下即可
                {
                    task.NextExecuteTime = now + (long)nextExecuteTimeSpan.TotalMilliseconds;
                    task.ModifyTime      = DateTime.Now;
                    await _aixScheduleTaskRepository.UpdateAsync(task);
                }

                nextExecuteDelays.Add(nextExecuteTimeSpan);
            }

            return(nextExecuteDelays);
        }