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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 【转载】软件架构设计【学习】

    【转载】软件架构设计【学习】

    2021年11月20日
    53
  • windows10 安装密钥_安装了pycharm还需要安装anaconda

    windows10 安装密钥_安装了pycharm还需要安装anaconda前言Python环境配置,有很多种组合方式,但是比较流行的是:Anaconda+Pycharm.第一部分:下载及安装Anaconda1.下载Anaconda安装包,官网下载地址:https://www.anaconda.com/download/选择64-bit的python3.7下载安装Anaconda下载后的文件为.exe文件,双击该文件进入安装界面。  2.1、依次…

    2022年8月29日
    2
  • PV操作——生产者和消费者

    PV操作——生产者和消费者

    2022年1月15日
    62
  • Jmeter安装步骤「建议收藏」

    Jmeter安装步骤「建议收藏」1、官网下载地址:http://jmeter.apache.org/download_jmeter.cgi2、下载到本地(我是D盘中:存放目录最好都是英文)3、配置环境变量:(window10:设置-》系统-》关于-》系统信息-》高级系统设置-》-OK)4、此处为我的安装目录:变量名称 变量值 JMETER_HOME D:\testsoft\apac…

    2022年6月5日
    26
  • 3.3转1.8V(电平转换)_i2c电平转换芯片国产

    3.3转1.8V(电平转换)_i2c电平转换芯片国产利用TI电平钳制芯片SN74TVC16222A来做电平转换,优点在于速率可以做得快一些。

    2022年8月10日
    8
  • AE图床-图床聚合源码

    AE图床-图床聚合源码介绍:一个图床聚合程序,自带鉴黄功能,违规图片智能拦截可以直接复制上传以后的链接以及预览支持5个接口上传,图片都支持https永久免费图床,无需注册,批量上传,即时预览,无限流量,无限外链,永久保存,微博服务器,全网CDN,高速稳定,网页上传,无需插件。支持JPG,GIF,PNG等文件格式。支持远程图片上传。微博图床,围脖是个好图床。网盘下载地址:https://zijiewangpan.com/cH4upvpuqQw图片:…

    2022年5月8日
    44

发表回复

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

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