LoopBox 用于包装循环的盒子

LoopBox 用于包装循环的盒子LoopBox 用于包装循环的盒子

大家好,又见面了,我是你们的朋友全栈君。

/*******************************************************
 * 
 * 作者:朱皖苏
 * 创建日期:20180608
 * 说明:此文件只包含一个类,具体内容见类型注释。
 * 版本号:1.0.0
 * 
 * 历史记录:
 * 创建文件 朱皖苏 20180608 16:06
 * 
*******************************************************/

using System;
using System.Diagnostics;
using System.Threading;

namespace Dben.CommonLib.LoopBox
{

    /// <summary>
    /// 封装了重复执行一段程序 n 次,它会额外输出每次处理耗时及计划完成时间。
    /// 继承此类以实现一个可配置的批处理数据程序。
    /// </summary>
    public abstract class LoopBox
    {
        /// <summary>
        /// 构造函数写入 <see cref="Context"/> 实例
        /// </summary>
        public LoopBox()
        {
            Context = InitContext();
        }

        /// <summary>
        /// 循环中的上下文对象
        /// </summary>
        protected ILoopContext Context { get; private set; }

        /// <summary>
        /// 循环执行任务。 box 的启动程序。
        /// </summary>
        /// <param name="loopBoxConfig"></param>
        public void Loop(LoopBoxConfig loopBoxConfig)
        {
            var log = $"处理计划:计划数据:{ loopBoxConfig.PlanTotal} 条,每次处理 {loopBoxConfig.LoopBatch} 条,共计处理 {loopBoxConfig.LoopCount}次";
            LogOutput(log);
            Context.Config = loopBoxConfig;
            var swItem = new Stopwatch();
            var swTotal = new Stopwatch();
            swTotal.Start();
            for (int i = 1; i <= loopBoxConfig.LoopCount; i++)
            {
                Context.Index = i;
                try
                {
                    swItem.Start();
                    Do();
                    swItem.Stop();
                    LogOutput($"第{i}/{loopBoxConfig.LoopCount}批执行完毕,执行耗时 {swItem.Elapsed.TotalSeconds} 秒,总耗时 {swTotal.Elapsed.TotalSeconds} 秒。预计剩余时间 {(loopBoxConfig.LoopCount - i == 0 ? 0 : swTotal.Elapsed.TotalSeconds / i * (loopBoxConfig.LoopCount - i))} 秒。 ");
                }
                catch (Exception e)
                {
                    LogOutput($"第{i}/{loopBoxConfig.LoopCount}批执行出现异常:{e.Message + e.StackTrace}");
                    throw e;
                }
                finally
                {
                    swItem.Reset();
                }
            }
            swTotal.Stop();
        }

        /// <summary>
        /// 初始化上下文对象,
        /// 需要提供一个简单的接口数据 <see cref="ILoopContext"/>/// 以确定执行 <see cref="Do"/> 的次数和输出执行的相关信息。
        /// 推荐使用默认 <see cref="DefaultLoopContext{T}"/>
        /// </summary>
        /// <returns></returns>
        protected abstract ILoopContext InitContext();

        /// <summary>
        /// 此函数为迭代中要执行的方法,
        /// <para>
        /// 相关的参数、结果的数据传递请使用自定义上下文或者继承<see cref="ILoopContext"/>,
        /// </para>
        /// 一般场景推荐使用默认的上下文对象<see cref="DefaultLoopContext{T}"/>
        /// </summary>
        protected abstract void Do();

        /// <summary>
        /// 此函数为 box 出口。实现此函数以及时响应程序执行过程和进度。
        /// </summary>
        /// <param name="log"></param>
        protected abstract void LogOutput(string log);
    }
}

/*******************************************************
 * 
 * 作者:朱皖苏
 * 创建日期:20180608
 * 说明:此文件只包含一个类,具体内容见类型注释。
 * 版本号:1.0.0
 * 
 * 历史记录:
 * 创建文件 朱皖苏 20180608 16:06
 * 
*******************************************************/

using System;
using System.Linq;

namespace Dben.CommonLib.LoopBox
{
    public class LoopBoxConfig
    {
        public LoopBoxConfig(long planTotal = 0, long loopBatch = 0, long loopCount = 0)
        {
            var items = new long[3] { planTotal, loopBatch, loopCount };

            if (items.Count(m => m < 1) >= 2)
            {
                throw new Exception("You can't have two or three attribute values that are less than zero at the same time.");
            }
            PlanTotal = planTotal;
            LoopBatch = loopBatch;
            LoopCount = loopCount;
        }

        private long loopCount;
        private long loopBatch;
        private long planTotal;
        public long LoopCount
        {
            get
            {
                if (loopCount < 1)
                {
                    loopCount = (long)Math.Ceiling((decimal)PlanTotal / LoopBatch);
                }
                return loopCount;
            }
            private set { loopCount = value; }
        }

        public long LoopBatch
        {
            get
            {
                if (loopBatch < 1)
                {
                    loopBatch = (long)Math.Ceiling((decimal)PlanTotal / LoopCount);
                }
                return loopBatch;
            }
            private set
            {
                loopBatch = value;
            }
        }

        public long PlanTotal
        {
            get
            {
                if (planTotal < 1)
                {
                    planTotal = LoopCount * LoopBatch;
                }
                return planTotal;
            }
            private set
            {
                planTotal = value;
            }
        }

    }
}

/*******************************************************
 * 
 * 作者:朱皖苏
 * 创建日期:20180608
 * 说明:此文件只包含一个类,具体内容见类型注释。
 * 版本号:1.0.0
 * 
 * 历史记录:
 * 创建文件 朱皖苏 20180608 16:06
 * 
*******************************************************/

namespace Dben.CommonLib.LoopBox
{
    public interface ILoopContext
    {
        LoopBoxConfig Config { get; set; }
        int Index { get; set; }
    }
}

/*******************************************************
 * 
 * 作者:朱皖苏
 * 创建日期:20180608
 * 说明:此文件只包含一个类,具体内容见类型注释。
 * 版本号:1.0.0
 * 
 * 历史记录:
 * 创建文件 朱皖苏 20180608 16:07
 * 
*******************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Dben.CommonLib.LoopBox
{
    /// <summary>
    /// 默认的上下文对象
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public sealed class DefaultLoopContext<T> : ILoopContext
    {
        public T Tag { get; set; }
        public LoopBoxConfig Config { get; set; }
        public int Index { get; set; }
    }
}

 

转载于:https://www.cnblogs.com/zhuwansu/p/10836926.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/106827.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • java策略模式例子(一个完整的java程序示例)

    以一个顾客价格计算策略为背景,写一个策略模式的demo参考代码:https://github.com/zhang-xiaoxiang/DesignPatterns23没有用策略模式我们一般是下面的写法,直接写一个类,在类里面直接写策略算法(功能实现)//packagecom.demo.strategy;/***NoStrategy:没有策略的做法*实现起来比较容…

    2022年4月14日
    51
  • 51单片机流水灯的三种实现方法「建议收藏」

    51单片机流水灯的三种实现方法「建议收藏」首先,介绍下原理。下图为主控芯片和流水灯模块的原理图。流水灯模块接在单片机的P1口,由原理图可以知道,在P1口给一个低电平即可点亮LED灯。相反,如果要LED灯熄灭,就要把P1口的电平变为高电平即可。要实现流水灯功能,我们只要将LED1~LED8依次点亮、熄灭,依始类推,8只LED变会一亮一暗的做流水灯了。              实现8个LED流水灯程序用中

    2022年5月30日
    48
  • 机器学习之特征归一化

    当数据集的数值属性具有非常大的比例差异,往往导致机器学习的算法表现不佳,当然也有极少数特例。在实际应用中,通过梯度下降法求解的模型通常需要归一化,包括线性回归、逻辑回归、支持向量机、神经网络等模型。但

    2021年12月30日
    56
  • linux如何设置环境变量_linux用户环境变量

    linux如何设置环境变量_linux用户环境变量linuxfvwm作用FVWM窗口管理器最早是对TWM的修改,可以追溯到1993年。经过几年的迭代,出现了一个可高度自定义的环境,其中可以配置任何行为,动作或事件。它支持自定义键绑定,鼠标手势,主题,脚本等。尽管FVWM在安装后立即可用,但其默认发行版仅提供绝对的最低配置。这是启动自己的自定义桌面环境的良好基础,但是,如果您只想将其用作桌面,则可能要安装由另一个用户分发的完整配置。…

    2022年9月28日
    0
  • js对日期进行升序排序

    js对日期进行升序排序

    2021年11月22日
    52
  • docker安装RabbitMQ「建议收藏」

    docker安装RabbitMQ「建议收藏」docker安装RabbitMQ查看仓库里的RabbitMQdockersearchrabbitmq安装RabbitMQdockerpullrabbitmq这里是直接安装最新的,如果需要安装其他版本在rabbitmq后面跟上版本号即可启动RabbitMQdockerrun-d–hostnamemy-rabbit–namerabbit-p15672:15672-p5672:5672rabbitmq安装插件先执行dockerps拿到当前的镜像ID

    2022年5月24日
    35

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号