此处耗时统计实际上采用的是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
}