protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            var cron = WeihanLi.Common.Helpers.Cron.CronExpression.Parse(CronExpression);

            var next = cron.GetNextOccurrence();

            while (!stoppingToken.IsCancellationRequested && next.HasValue)
            {
                var now = DateTimeOffset.UtcNow;

                if (now >= next)
                {
                    if (ConcurrentAllowed)
                    {
                        _    = ProcessAsync(stoppingToken);
                        next = CronHelper.GetNextOccurrence(CronExpression);
                        if (next.HasValue)
                        {
                            Logger.LogInformation("Next at {next}", next);
                        }
                    }
                    else
                    {
                        var firewall = RedisManager.GetFirewallClient($"Job_{GetType().FullName}_{next:yyyyMMddHHmmss}", TimeSpan.FromMinutes(3));
                        if (await firewall.HitAsync())
                        {
                            // 执行 job
                            await ProcessAsync(stoppingToken);

                            next = CronHelper.GetNextOccurrence(CronExpression);
                            if (next.HasValue)
                            {
                                Logger.LogInformation("Next at {next}", next);
                                var delay = next.Value - DateTimeOffset.UtcNow;
                                if (delay > TimeSpan.Zero)
                                {
                                    await Task.Delay(delay, stoppingToken);
                                }
                            }
                        }
                        else
                        {
                            Logger.LogInformation("正在执行 job,不能重复执行");
                            next = CronHelper.GetNextOccurrence(CronExpression);
                            if (next.HasValue)
                            {
                                await Task.Delay(next.Value - DateTimeOffset.UtcNow, stoppingToken);
                            }
                        }
                    }
                }
                else
                {
                    // needed for graceful shutdown for some reason.
                    // 1000ms so it doesn't affect calculating the next
                    // cron occurence (lowest possible: every second)
                    await Task.Delay(next.Value - DateTimeOffset.UtcNow, stoppingToken);
                }
            }
        }
예제 #2
0
        public static void MainTest()
        {
            // http://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger.html
            var nextTickUtc   = CronHelper.GetNextOccurrence("0 15 10 * * ?");
            var nextTickLocal = CronHelper.GetNextOccurrence("0 15 10 * * ?", TimeZoneInfo.Local);

            Console.WriteLine($"@utc next tick: {nextTickUtc.GetValueOrDefault().DateTime.ToStandardTimeString()}  {Environment.NewLine} local next tick:{nextTickLocal.GetValueOrDefault().DateTime.ToStandardTimeString()}");

            var nextTicks = CronHelper.GetNextOccurrences("0 15 10-20 * * ?", TimeSpan.FromHours(6), TimeZoneInfo.Local).Take(5).ToArray();

            foreach (var tick in nextTicks)
            {
                Console.WriteLine(tick.DateTime.ToStandardTimeString());
            }
        }