• 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; }
        }
    }
  • 相关阅读:
    SubString函数总结
    button按钮居中
    2019 面试题
    linux(centos)搭建SVN服务器
    svn 设置钩子将代码同步到web目录下面
    sql 语句总结
    php 多维数组转换
    php 两个数组是否相同,并且输出全面的数据,相同的加一个字段标示
    PHP错误类型及屏蔽方法
    设置div中文字超出时自动换行
  • 原文地址:https://www.cnblogs.com/zhuwansu/p/10836926.html
Copyright © 2020-2023  润新知