上次我发布了一个用以在记录文件中写入自定义的调试信息(主要是时间)的组件,但由于CLR的限制,它只能精确到10毫秒左右。后来我参考了网络上的一篇文章:http://blog.joycode.com/lostinet/archive/2005/04/24/49590.aspx(在这里首先向原作者表示感谢)通过调用系统API得到了可精确到1毫秒左右的时间记录。故特重新用C#重写了这个组件,与大家共享。
//==================================================================== //TraceSpy - 用以在记录文件中写入自定义的调试信息(开发者:林健) //==================================================================== // //属性: // TraceFileName - 记录文件名 // //方法: // ★文本写入方面 // WriteText - 写入自定义文本 // ClearAllText - 清除所有文本 // ★时间记录方面 // SetTimePoint - 设置时间起点 // GetTimeSpanFromInit - 询问时间跨度(距离时间起点) // GetTimeSpanFromPrev - 询问时间跨度(距离上次询问时间) // ★自定义计数器 // SetCounter - 设置自定义计数器 // AddCounter - 累加自定义计数器 // //==================================================================== using System; namespace TraceSpy { public class TheTrace { //记录文件名 static public string TraceFileName = "Trace.txt"; //时间起点(初始为当前时刻) static private long InitTimePoint = TimeCounter.GetExactNow().Ticks; //上次询问时间点(初始为当前时刻) static private long PrevTimePoint = TimeCounter.GetExactNow().Ticks; //自定义计数器 static private int counter = 0; //写入自定义文本 static public void WriteText(string str) { WriteText(str, false); } static public void WriteText(string str, bool showTime) { FileWriter.WriteText(str, showTime); } //清除所有文本 static public void ClearAllText() { FileWriter.ClearAllText(); } //设置时间起点 static public void SetTimePoint() { SetTimePoint(""); } static public void SetTimePoint(string note) { InitTimePoint = TimeCounter.GetExactNow().Ticks; PrevTimePoint = TimeCounter.GetExactNow().Ticks; FileWriter.WriteText("设置时间起点[" + note + "]。", false); } //询问时间跨度(距离时间起点) static public decimal GetTimeSpanFromInit() { return GetTimeSpanFromInit(""); } static public decimal GetTimeSpanFromInit(string note) { PrevTimePoint = TimeCounter.GetExactNow().Ticks; decimal span; span = (decimal)(PrevTimePoint - InitTimePoint) / (decimal)10000; FileWriter.WriteText("询问时间跨度[" + note + "],距离时间起点为" + span.ToString() + "毫秒。", false); return span; } //询问时间跨度(距离上次询问时间) static public decimal GetTimeSpanFromPrev() { return GetTimeSpanFromPrev(""); } static public decimal GetTimeSpanFromPrev(string note) { long RectTimePoint =TimeCounter.GetExactNow().Ticks; decimal span; span = (decimal)(RectTimePoint - PrevTimePoint) / (decimal)10000; PrevTimePoint = RectTimePoint; FileWriter.WriteText("询问时间跨度[" + note + "],距离上次询问时间为" + span.ToString() + "毫秒。", false); return span; } //设置自定义计数器 static public int SetCounter() { return SetCounter(0); } static public int SetCounter(int num) { counter = num; FileWriter.WriteText("自定义计数器值设置为" + counter + "。", false); return counter; } //累加自定义计数器 static public int AddCounter() { return AddCounter(1); } static public int AddCounter(int num) { counter += num; FileWriter.WriteText("自定义计数器值累加到" + counter + "。", false); return counter; } } } using System; using System.Runtime.InteropServices; namespace TraceSpy { internal class TimeCounter { [DllImport("kernel32.dll")] static extern bool QueryPerformanceCounter([In, Out] ref long lpPerformanceCount); [DllImport("kernel32.dll")] static extern bool QueryPerformanceFrequency([In, Out] ref long lpFrequency); static long _f = 0; static private long GetTickCount() { long f = _f; if (f == 0) { if (QueryPerformanceFrequency(ref f)) { _f = f; } else { _f = -1; } } if (f == -1) { return Environment.TickCount * 10000; } long c = 0; QueryPerformanceCounter(ref c); return (long)(((double)c) * 1000 * 10000 / ((double)f)); } static long _tc = 0; static internal DateTime GetExactNow() { if (_tc == 0) { long tc = GetTickCount(); DateTime dt = DateTime.Now; _tc = dt.Ticks - tc; return dt; } return new DateTime(_tc + GetTickCount()); } } } using System; namespace TraceSpy { internal class FileWriter { static private System.IO.StreamWriter writer; //向文件中写入一个字串 static internal void WriteText(string str, bool showTime) { if(TheTrace.TraceFileName == String.Empty) return; writer = new System.IO.StreamWriter(TheTrace.TraceFileName, true, System.Text.Encoding.Default); string words; words = str; if(showTime) words += " @ " + TimeCounter.GetExactNow().ToLongDateString() + " " + TimeCounter.GetExactNow().ToLongTimeString(); writer.WriteLine(words); writer.Close(); } //清除记录文件 static internal void ClearAllText() { if(TheTrace.TraceFileName == String.Empty) return; writer = new System.IO.StreamWriter(TheTrace.TraceFileName, false, System.Text.Encoding.Default); writer.Write(""); writer.Close(); } } } 作者Blog:http://blog.csdn.net/sswv/
|