上次我发布了一个用以在记录文件中写入自定义的调试信息(主要是时间)的组件,但由于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();
}
}
}