天天看点

C# 耗时统计器(简单)

此处耗时统计实际上采用的是Stopwatch ,因为耗时统计对时间要求比较严苛,

本文所采用方法其实理论上只是用来方便统计、可能准确度上让人不大放心。

本文只是做了个简单的封装、准确度上差别应该不是问题。

调用方法见代码summary

///<summary>耗时统计
    ///<para>建议采用关闭时写入、实时写入日志等耗时操作将严重影响统计</para>  
    ///<para>初始化:string TJGuid = WatchTimerHelper.WatchTimerStart("计时器001")</para>  
    ///<para>追加消息:WatchTimerHelper.WatchTimerMsgAttach(TJGuid, "预警项目");</para>  
    ///<para>关闭:WatchTimerHelper.WatchTimerStop(TJGuid);</para>  
    ///</summary>
    public class WatchTimerHelper
    {
        #region 私有属性

        private static Dictionary<string, StopwatchEx> _m_WatchTimerDic = new Dictionary<string, StopwatchEx>();

        #endregion

        #region 枚举结构

        /// <summary>
        /// 统计器描述
        /// </summary>
        public class StopwatchDesc 
        {
            /// <summary>
            /// 计时器唯一表示
            /// </summary>
            public string m_WatchGuid { get; set; }

            /// <summary>
            /// 计时器名称
            /// </summary>
            public string m_WatchName { get; set; }

            public E_RaiseType m_RaiseType{get;set;}

            public E_RaiseTime m_RaiseTime { get; set; }
        }

        /// <summary>
        /// 统计器时间线
        /// </summary>
        private class StopwatchTimeLine 
        {
            /// <summary>
            /// 当前时间点运行总时
            /// </summary>
            public TimeSpan Elapsed { get; set; }
            /// <summary>
            /// 当前时间点运行总时 - 毫秒
            /// </summary>
            public long ElapsedMilliseconds { get; set; }
            /// <summary>
            /// 当前时间点运行总时 - 秒
            /// </summary>
            public long ElapsedTicks { get; set; }

            public string Msg { get; set; }
        }

        /// <summary>
        /// 统计器
        /// </summary>
        private class StopwatchEx : Stopwatch
        {
            public StopwatchDesc m_StopwatchDesc { get; set; }

            public List<StopwatchTimeLine> m_RaisTimeLine_List { get; set; }
        }

        /// <summary>
        /// 统计输出类型
        /// </summary>
        public enum E_RaiseType 
        { 
            /// <summary>
            /// 控制台
            /// </summary>
            Console = 0x01,
        }

        /// <summary>
        /// 统计时间输出类型
        /// </summary>
        public enum E_RaiseTime 
        { 
            /// <summary>
            /// 实时
            /// </summary>
            RealTime = 0x01,

            /// <summary>
            /// 关闭时输出
            /// </summary>
            StopTime = 0x02,
        }

        #endregion

        #region 公共属性



        #endregion

        #region 公共方法

        /// <summary>
        /// 开启耗时统计
        /// </summary>
        public static string WatchTimerStart(string WatchName,E_RaiseTime RaiseTime = E_RaiseTime.RealTime, E_RaiseType RaiseType = E_RaiseType.Console)
        {
           
            //统计器初始化
            StopwatchEx watch = new StopwatchEx();
            watch.m_StopwatchDesc = new StopwatchDesc() { m_WatchGuid = Guid.NewGuid().ToString(), m_WatchName = WatchName, m_RaiseTime = RaiseTime, m_RaiseType = RaiseType };
            watch.m_RaisTimeLine_List = new List<StopwatchTimeLine>();
            _m_WatchTimerDic.Add(watch.m_StopwatchDesc.m_WatchGuid, watch);
             
            //开始统计
            watch.Start();

            //附加消息
            WatchTimerMsgAttach(watch.m_StopwatchDesc.m_WatchGuid, "统计器开启!");

            return watch.m_StopwatchDesc.m_WatchGuid;
        }

        /// <summary>
        /// 关闭耗时统计
        /// </summary>
        public static void WatchTimerStop(string WatchGuid)
        {
            if (_m_WatchTimerDic.ContainsKey(WatchGuid) == false)
            {
                return ;
            }
            _m_WatchTimerDic[WatchGuid].Stop();

            //附加消息 - 输出
            WatchTimerMsgAttach(WatchGuid, "统计器结束!");

            //去除统计器
            _m_WatchTimerDic[WatchGuid] = null;
            _m_WatchTimerDic.Remove(WatchGuid);
        }

        /// <summary>
        /// 统计器附加消息
        /// </summary>
        /// <param name="WatchGuid"></param>
        /// <param name="Msg"></param>
        public static void WatchTimerMsgAttach(string WatchGuid,string Msg)
        {
            if (_m_WatchTimerDic.ContainsKey(WatchGuid) == false)
            {
                return;
            }
            var watch = _m_WatchTimerDic[WatchGuid];
            
            StringBuilder SB = new StringBuilder();
            //统计器描述
            SB.AppendFormat("================================ {0} ================================\r\n",watch.m_StopwatchDesc.m_WatchName);
            //标识及时间
            SB.AppendFormat("Guid:{0}\tTime:{1}\r\n", watch.m_StopwatchDesc.m_WatchGuid, DateTime.Now.ToString("yyyy-MM-dd"));
            //附加消息
            SB.AppendFormat("Message:{0}\r\n",Msg);
            //时间统计 - 总时秒,总时毫秒,上次总时间
            SB.AppendFormat("Times(S):{0}\tTimes(ms):{1}\tTimeSpace(ms):{2}\r\n", watch.ElapsedTicks, watch.ElapsedMilliseconds, watch.m_RaisTimeLine_List.Count > 0 ? (watch.ElapsedMilliseconds - watch.m_RaisTimeLine_List[watch.m_RaisTimeLine_List.Count - 1].ElapsedMilliseconds) : 0);
            //继续换行
            SB.Append("\r\n");

            //消息队列
            string ActualMsg = SB.ToString();
            StopwatchTimeLine Line = new StopwatchTimeLine()
            {
                Elapsed = watch.Elapsed,
                ElapsedMilliseconds = watch.ElapsedMilliseconds,
                ElapsedTicks = watch.ElapsedTicks,
                Msg = ActualMsg,
            };
            watch.m_RaisTimeLine_List.Add(Line);

            switch (watch.m_StopwatchDesc.m_RaiseTime)
            {
                case E_RaiseTime.RealTime: //实时
                    {
                        OutPutWatchMsg_RealTime(watch, ActualMsg);
                    } break;
                case E_RaiseTime.StopTime: //退出
                    {
                        OutPutWatchMsg_StopTime(watch);
                    } break;
            }
        }

        #endregion

        #region 私有方法

        #region 实时输出

        /// <summary>
        /// 实时输出
        /// </summary>
        /// <param name="watch"></param>
        /// <param name="Msg"></param>
        private static void OutPutWatchMsg_RealTime(StopwatchEx watch, string Msg)
        {
            switch (watch.m_StopwatchDesc.m_RaiseType)
            {
                case E_RaiseType.Console: //控制台输出
                    {
                        OutPutWatchMsg_RealTime_Console(Msg);
                    } break;
            }
        }

        /// <summary>
        /// 实时输出 - 控制台
        /// </summary>
        /// <param name="Msg"></param>
        private static void OutPutWatchMsg_RealTime_Console(string Msg)
        {
            Console.Write(Msg);
        }

        #endregion

        #region 关闭时输出

        /// <summary>
        /// 关闭时输出
        /// </summary>
        /// <param name="watch"></param>
        /// <param name="Msg"></param>
        private static void OutPutWatchMsg_StopTime(StopwatchEx watch)
        {
            switch (watch.m_StopwatchDesc.m_RaiseType)
            {
                case E_RaiseType.Console: //控制台输出
                    {
                        OutPutWatchMsg_StopTime_Console(watch);
                    } break;
            }
        }

        /// <summary>
        /// 关闭时输出 - 控制台
        /// </summary>
        /// <param name="Msg"></param>
        private static void OutPutWatchMsg_StopTime_Console(StopwatchEx watch)
        {
            if (watch.m_RaisTimeLine_List.Count <= 0)
            {
                return;
            }
            foreach (var item in watch.m_RaisTimeLine_List)
            {
                Console.Write(item);
            }
        }

        #endregion

        #endregion
    }