/*******************************************************
*
* 作者:朱皖苏
* 创建日期: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 = ; 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 = , long loopBatch = , long loopCount = )
{
var items = new long[] { planTotal, loopBatch, loopCount }; if (items.Count(m => m < ) >= )
{
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 < )
{
loopCount = (long)Math.Ceiling((decimal)PlanTotal / LoopBatch);
}
return loopCount;
}
private set { loopCount = value; }
} public long LoopBatch
{
get
{
if (loopBatch < )
{
loopBatch = (long)Math.Ceiling((decimal)PlanTotal / LoopCount);
}
return loopBatch;
}
private set
{
loopBatch = value;
}
} public long PlanTotal
{
get
{
if (planTotal < )
{
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; }
}
}

LoopBox 用于包装循环的盒子的更多相关文章

  1. python让实例作用于for循环并当做list来使用

    python如果想让一个类被用于for....in  循环,类型list和tuple那样,可以实现__iter__方法. 这个方法返回一个迭代对象,python的for循环就会不断调用该迭代对象的ne ...

  2. javascript语句——条件语句、循环语句和跳转语句

    × 目录 [1]条件语句 [2]循环语句 [3]跳转语句 前面的话 默认情况下,javascript解释器依照语句的编写顺序依次执行.而javascript中的很多语句可以改变语句的默认执行顺序.本文 ...

  3. 如何在 iOS 中解决循环引用的问题

    稍有常识的人都知道在 iOS 开发时,我们经常会遇到循环引用的问题,比如两个强指针相互引用,但是这种简单的情况作为稍有经验的开发者都会轻松地查找出来. 但是遇到下面这样的情况,如果只看其实现代码,也很 ...

  4. CSS基础之盒子模型及浮动布局

    盒模型 谈到盒模型,有经验的小伙伴一定滚瓜烂熟,无非就是 内容(content).填充(padding).边框(border).边界(margin): 这些属性我们可以把它转移到我们日常生活中的盒子( ...

  5. 烂大街的 Spring 循环依赖问题,你觉得自己会了吗

    文章已收录在 GitHub JavaKeeper ,N 线互联网开发.面试必备技能兵器谱,笔记自取. 微信搜「 JavaKeeper 」程序员成长充电站,互联网技术武道场.无套路领取 500+ 本电子 ...

  6. Spring的循环依赖,学就完事了【附源码】

    目录 啥是循环依赖? Spring可以解决循环依赖的条件 Spring如何去解决循环依赖 SpringBean的创建流程 Spring维护的三级缓存 getSingleton getSingleton ...

  7. 3.4 spring5源码系列--循环依赖的设计思想

    前面已经写了关于三篇循环依赖的文章, 这是一个总结篇 第一篇: 3.1 spring5源码系列--循环依赖 之 手写代码模拟spring循环依赖 第二篇: 3.2spring源码系列----循环依赖源 ...

  8. 四探循环依赖 → 当循环依赖遇上 BeanPostProcessor,爱情可能就产生了!

    开心一刻 那天知道她结婚了,我整整一个晚上没睡觉,开了三百公里的车来到她家楼下,缓缓的抽了一支烟...... 天渐渐凉了,响起了鞭炮声,迎亲车队到了,那天披着婚纱的她很美,真的很美! 我跟着迎亲车队开 ...

  9. 关于for循环------swift3.0

    在程序开发当中,for循环使用的频率无疑是最高的.常用的swift循环是递增式遍历.当然各种循环,swift都能办到.但其大多采用关键字形式实现,大部分开发者更喜欢直接使用C式循环代码.在swift3 ...

随机推荐

  1. 理解java面向对象基础

    1. 类和对象 一切皆对象,这可以说是面向对象的核心思想了. 类,就是具有相同性质对象的抽象. 而类的每一个具体的实例就是一个对象. 我们可以定义一个Person类,这个Person类就是所有的人的抽 ...

  2. Springboot 2.x下多数据源配置

    本文同样适用于2.x版本下Mybatis的多数据源配置 项目中经常会遇到一个项目需要访问多个数据源的情况,多数情况下可以参考这个教程进行配置. 不过该教程适合springboot1.x版本,由于2.x ...

  3. Codeforces Round #178 (Div. 2)

    A. Shaass and Oskols 模拟. B. Shaass and Bookshelf 二分厚度. 对于厚度相同的书本,宽度竖着放显然更优. 宽度只有两种,所以枚举其中一种的个数,另一种的个 ...

  4. win10下,cmd,power shell设置默认编码为‘UTF-8’?

    这个问题可以终结了,最新版 Windows 10 支持 UTF-8 了.打开这个选项,cmd 和 powershell 默认就是 UTF-8 了.在控制面板-时钟和区域-区域-管理-更改系统区域设置( ...

  5. 11584 - Partitioning by Palindromes——[DP]

    题意分析: 题目比较容易理解,以d[i]表示前i个字符的最优解,状态转移方程 d[i]=min{d[j]+1| [j+1~i]为回文串} 代码如下: #include <cstdio> # ...

  6. JAVA核心知识点--打包 FatJar 方法小结

    目录 什么是 FatJar 三种打包方法 1. 非遮蔽方法(Unshaded) 2. 遮蔽方法(Shaded) 3. 嵌套方法(Jar of Jars) 小结 参考阅读 原文地址:https://yq ...

  7. Spring Security学习笔记-自定义Spring Security过滤链

    Spring Security使用一系列过滤器处理用户请求,下面是spring-security.xml配置文件. <?xml version="1.0" encoding= ...

  8. Loj3033 JOISC 2019 Day2两个天线

    Loj3033 JOISC 2019 Day2两个天线 下午唯一听懂的题目但,但还是比较模糊.写一篇题解来加深一下印象. 题目大意:给定\(n\)根天线,第\(i\)跟天线的高度为\(h_i\),切它 ...

  9. 慕课网electron写音乐播放器教程,代码跟随教程变动(十)

    添加播放状态,首先是歌曲名称和时间 在index.html中添加 <div class="container fixed-bottom bg-white pb-4"> ...

  10. js 快速取整

    我们要将23.8转化成整数  有哪些方法呢 比如 Math.floor( ) 对数进行向下取整  它返回的是小于或等于函数参数,并且与之最接近的整数 Math.floor(5.1) 返回值 //5 M ...