diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobCreator.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobCreator.cs index 91e40d67b..43f82c739 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobCreator.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobCreator.cs @@ -125,11 +125,21 @@ public class QuartzJobCreator : IQuartzJobCreator, ISingletonDependency triggerBuilder .WithIdentity(KeyBuilder.CreateTriggerKey(job)) .WithDescription(job.Description) - .StartAt(Clock.Now.AddSeconds(job.Interval)) .EndAt(job.EndTime) .ForJob(KeyBuilder.CreateJobKey(job)) .WithPriority((int)job.Priority); - + + // 首次启动时间由 BeginTime 决定,不再使用 Interval 作为"延迟启动"。 + // Interval 仅在 Persistent 周期任务中表示"重复间隔"。 + if (job.BeginTime > Clock.Now) + { + triggerBuilder.StartAt(job.BeginTime); + } + else + { + triggerBuilder.StartNow(); + } + // Quartz约定. 重复间隔不能为0 // fix throw Quartz.SchedulerException: Repeat Interval cannot be zero. var scheduleBuilder = SimpleScheduleBuilder.Create(); @@ -139,14 +149,8 @@ public class QuartzJobCreator : IQuartzJobCreator, ISingletonDependency { scheduleBuilder.WithRepeatCount(maxCount); } - if (job.Interval > 0) - { - scheduleBuilder.WithIntervalInSeconds(job.Interval); - } - else - { - scheduleBuilder.WithIntervalInSeconds(300); - } + scheduleBuilder.WithIntervalInSeconds(job.Interval > 0 ? job.Interval : 300); + triggerBuilder.WithSchedule(scheduleBuilder); diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/BackgroundJobManager.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/BackgroundJobManager.cs index edc460e4e..ded32941d 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/BackgroundJobManager.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/BackgroundJobManager.cs @@ -47,33 +47,36 @@ public class BackgroundJobManager : IBackgroundJobManager TimeSpan? delay = null) { var jobConfiguration = Options.GetJob(); - var interval = 0; - if (delay.HasValue) - { - interval = delay.Value.Seconds; - } - var jobId = GuidGenerator.Create(); - var jobArgs = new Dictionary - { - { nameof(TArgs), JsonSerializer.Serialize(args) }, - { "ArgsType", jobConfiguration.ArgsType.AssemblyQualifiedName }, - { "JobType", jobConfiguration.JobType.AssemblyQualifiedName }, - { "JobName", jobConfiguration.JobName }, - }; - var jobInfo = new JobInfo - { - Id = jobId.ToString(), - TenantId = CurrentTenant.Id, - Name = jobId.ToString(), - Group = "BackgroundJobs", - Priority = ConverForm(priority), - Source = JobSource.System, - BeginTime = DateTime.Now, - Args = jobArgs, - Description = "From the framework background jobs", - JobType = JobType.Once, - Interval = interval, - CreationTime = Clock.Now, + // 用 BeginTime 表达延迟启动,避免与 JobInfo.Interval(重复间隔)语义混用。 + // 原实现使用 delay.Value.Seconds(仅取秒分量 0-59), + // 会让 TimeSpan.FromMinutes(5) 这类整分钟/整小时的延迟退化为 0,导致任务立即执行。 + var now = Clock.Now; + var beginTime = now; + if (delay.HasValue && delay.Value > TimeSpan.Zero) + { + beginTime = now.Add(delay.Value); + } + var jobId = GuidGenerator.Create(); + var jobArgs = new Dictionary + { + { nameof(TArgs), JsonSerializer.Serialize(args) }, + { "ArgsType", jobConfiguration.ArgsType.AssemblyQualifiedName }, + { "JobType", jobConfiguration.JobType.AssemblyQualifiedName }, + { "JobName", jobConfiguration.JobName }, + }; + var jobInfo = new JobInfo + { + Id = jobId.ToString(), + TenantId = CurrentTenant.Id, + Name = jobId.ToString(), + Group = "BackgroundJobs", + Priority = ConverForm(priority), + Source = JobSource.System, + BeginTime = beginTime, + Args = jobArgs, + Description = "From the framework background jobs", + JobType = JobType.Once, + CreationTime = now, // 确保不会被轮询入队 Status = JobStatus.None, NodeName = TasksOptions.NodeName,