zoukankan      html  css  js  c++  java
  • 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; }
        }
    }
  • 相关阅读:
    模拟实现bind、call、apply函数
    模拟实现ECMAScript5新增的数组方法
    HBuilder mui页面间传值的几种方式
    手机端软键盘弹出挤压页面的问题
    js获取当前时间
    原生js根据class获取元素的方法
    jquery之获取select选中的值
    原生js获取元素属性值方法
    利用javascrit获取url传递的参数
    jQuery图片预加载(延迟加载)之插件Lazy Load
  • 原文地址:https://www.cnblogs.com/zhuwansu/p/10836926.html
Copyright © 2011-2022 走看看