Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

限制任务执行次数,执行最短时间 #49

Open
lindexi opened this issue Apr 14, 2021 · 1 comment
Open

限制任务执行次数,执行最短时间 #49

lindexi opened this issue Apr 14, 2021 · 1 comment

Comments

@lindexi
Copy link
Member

lindexi commented Apr 14, 2021

将 IConditionExecutor 和 PeriodTaskWithConfigurationFile 开源

@lindexi lindexi changed the title 限制任务执行次数,或者限制任务执行最短时间 限制任务执行次数,执行最短时间 Apr 14, 2021
@lindexi
Copy link
Member Author

lindexi commented Dec 18, 2021

    /// <summary>
    /// 通过配置文件实现的间隔循环任务
    /// </summary>
    public static class PeriodTaskWithConfigurationFile
    {
        /// <summary>
        /// 设置将超过了 <see cref="delayTime"/> 之后,才允许再次执行的任务
        /// <para>
        /// 如用来做上报任务,如果三天内上报过,那么则不再上报,等再过三天才允许执行上报
        /// </para>
        /// <para>
        /// 原理是在 <paramref name="configurator"/> 配置文件,记录 <paramref name="taskName"/> 的上次执行时间,和当前对比,如果超过了 <paramref name="delayTime"/> 则执行
        /// </para>
        /// </summary>
        /// <param name="configurator"></param>
        /// <param name="taskName">任务名,要求是变量标识符</param>
        /// <param name="delayTime"></param>
        /// <param name="action"></param>
        /// <param name="currentTime">当前的时间,默认就是 DateTimeOffset.Now 的值。使用 DateTimeOffset 而不使用 DateTime 是因为 DateTimeOffset 可以加上本地时区</param>
        /// <returns>如果能执行,则返回 true 值</returns>
        public static bool Run(IAppConfigurator configurator, string taskName, TimeSpan delayTime, Action action,
            DateTimeOffset? currentTime = null)
        {
            if (string.IsNullOrEmpty(taskName))
            {
                throw new ArgumentNullException(nameof(taskName));
            }

            currentTime ??= DateTimeOffset.Now;

            var configurationKey = $"{nameof(PeriodTaskWithConfigurationFile)}.{taskName}.LastRunTime";
            var lastRunTime = configurator.Default[configurationKey];
            // 没有记录或超过指定时间,则运行
            if (lastRunTime == null
                // 无法解析为时间,那么认为数据损坏,继续运行
                || !DateTimeOffset.TryParse(lastRunTime, out var time)
                // 超过指定时间
                || currentTime - time > delayTime)
            {
                action();

                // 写入本次执行成功时间,如果执行炸了…… 就不记录了
                configurator.Default[configurationKey] = currentTime.Value.ToString("O");
                return true;
            }

            return false;
        }
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant