using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Sci
{
/// <summary>
/// 统计代码运行时长(用于记录代码执行耗时信息)
/// </summary>
public class LogTime
{
/// <summary>
/// 示例
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public static void example(object sender, EventArgs e)
{
LogTime.Start();
// 待统计时长的代码...
string timeStr = LogTime.CurrentStackTrace();
MessageBox.Show(timeStr);
LogTime.End("自定义注释信息"); // LogTime.End();
}
static Dictionary<string, long> timeDic = new Dictionary<string, long>();
/// <summary>
/// 记录log的开始时间
/// </summary>
/// <param name="tag"></param>
/// <returns></returns>
public static void Start()
{
string key = CurrentMethod(2) + System.Threading.Thread.CurrentThread.ManagedThreadId; // 获取调用Start()函数的函数名
timeDic.Add(key, DateTime.Now.Ticks); // 记录当前调用时间
}
/// <summary>
/// 记录指定log的结束时间
/// </summary>
public static void End(string msg = "")
{
long curTime = DateTime.Now.Ticks;
string key = CurrentMethod(2) + System.Threading.Thread.CurrentThread.ManagedThreadId; // 获取调用End()函数的函数名
if (timeDic.ContainsKey(key))
{
long preTime = timeDic[key]; // 获取Start()函数的调用时间
if (msg.Length > 0) msg = "(" + msg + ")";
string info = " " + CurrentMethod(2) + msg + " -> 执行耗时: " + getTimeSpan(curTime, preTime); // 生成耗时信息
ThreadPool.QueueUserWorkItem((state) => { Write(info); }); // 记录至log中
timeDic.Remove(key);
}
}
/// <summary>
/// 获取调用当前函数的方法名(索引1),
/// </summary>
/// <returns></returns>
public static string CurrentMethod(int index = 1)
{
StackTrace stackTrace = new StackTrace();
StackFrame stackFrame = stackTrace.GetFrame(index);
return ToString(stackFrame, true);
}
/// <summary>
/// 获取当前调用堆栈信息
/// </summary>
/// <returns></returns>
public static string CurrentStackTrace()
{
return ToString(new StackTrace());
}
private static string ToString(StackTrace stackTrace, bool simple = false)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < stackTrace.FrameCount; i++)
{
StackFrame stackFrame = stackTrace.GetFrame(i);
sb.AppendLine(ToString(stackFrame, simple));
}
return sb.ToString();
}
private static string ToString(StackFrame stackFrame, bool simple = false)
{
if (simple) return stackFrame.GetMethod() + " ";
else return stackFrame.GetFileName() + " -> " + stackFrame.GetMethod() + ",行号:" + stackFrame.GetFileLineNumber() + ",列号:" + stackFrame.GetFileColumnNumber();
}
static int[] unit = { 1000, 1000, 60, 60, 60, 24, 365 };
static string[] unitName = { "微秒", "毫秒", "秒", "分", "时", "天", "年" };
/// <summary>
/// 获取耗时时长
/// </summary>
/// <param name="curTime"></param>
/// <param name="preTime"></param>
/// <returns></returns>
private static string getTimeSpan(long curTime, long preTime)
{
long tickSpan = (curTime - preTime) / 10;
if (tickSpan < 0) tickSpan = -tickSpan;
string timeStr = "";
for (int i = 0; i < unit.Length; i++)
{
int unitI = unit[i];
if (tickSpan % unitI >= 0) timeStr = (tickSpan % unitI) + unitName[i] + timeStr;
if (tickSpan > unitI) tickSpan = tickSpan / unitI;
else break;
}
return timeStr;
}
/// <summary>
/// 向TimeLog中添加信息
/// </summary>
/// <param name="info"></param>
/// <param name="newLine"></param>
/// <param name="time"></param>
/// <returns></returns>
public static bool Write(string info, bool newLine = true, bool time = true)
{
try
{
string logPath = Application.StartupPath + "\\LogTime";
if (!Directory.Exists(logPath))
{
Directory.CreateDirectory(logPath);
}
string threadId = System.Threading.Thread.CurrentThread.ManagedThreadId + "";
logPath = logPath + "\\" + DateTime.Now.ToString("yyyyMMdd_HH") + ((DateTime.Now.Minute / 5 * 5) + "").PadLeft(2, '0') + "00_" + threadId + ".txt"; // 每5分钟,输出至一个log文件中,不同线程输出至不同文件中
string data = info;
if (time) data = "[" + DateTime.Now.ToString("HH:mm:ss") + "] " + data;
if (newLine) data = "\r\n" + data;
File.AppendAllText(logPath, data, Encoding.Unicode);
return true;
}
catch (Exception)
{
return false;
}
}
}
}