C# windows服务中System.Threading.Timer的准确性
我在C# windows服务中System.Threading.Timer的准确性,c#,.net,multithreading,windows-services,C#,.net,Multithreading,Windows Services,我在C#NET中开发了windows服务。 在本文中,我使用了System.Threading.Timer。 当我启动10秒间隔计时器时,执行时间之间会有一些变化 //code public void SetTimers(int timer, DataRow row) { TimeSpan dueTime; TimeSpan interval; SetTimeIntervals(row, out dueTime, o
C#NET
中开发了windows服务。
在本文中,我使用了System.Threading.Timer
。
当我启动10秒间隔计时器时,执行时间之间会有一些变化
//code
public void SetTimers(int timer, DataRow row)
{
TimeSpan dueTime;
TimeSpan interval;
SetTimeIntervals(row, out dueTime, out interval);
timer1[timer] = new System.Threading.Timer(databaseTrensfer, row, dueTime, interval);
}
public void databaseTrensfer()
{
//code
}
private void SetTimeIntervals(DataRow row, out TimeSpan tsDueTime, out TimeSpan tsPeriod)
{
string alarmType = Convert.ToString(row["EBase"]);
string EType = Convert.ToString(row["EType"]);
string EFrequency = Convert.ToString(row["EFrequncy"]);
if (alarmType == "Milisecond")
{
int frquency1 = Convert.ToInt32(row["Tfrquency"]);
tsDueTime = new TimeSpan(0, 0, 0, 0, frquency1);//frquency1=interval
tsPeriod = new TimeSpan(0, 0, 0, 0, frquency1);
}
else if (alarmType == "Second")
{
int frquency1 = Convert.ToInt32(row["Tfrquency"]);
tsDueTime = new TimeSpan(0, 0, 0, frquency1);
tsPeriod = new TimeSpan(0, 0, 0, frquency1);
}
else if (alarmType == "Once")
{
tsDueTime = new TimeSpan(0, 0, 0);
tsPeriod = new TimeSpan(0, 0, 0);
}
else if (alarmType == "Minute")
{
int frquency1 = Convert.ToInt32(row["Tfrquency"]);
tsDueTime = new TimeSpan(0, frquency1, 0);
tsPeriod = new TimeSpan(0, frquency1, 0);
}
else if (alarmType == "Hour")
{
int minute = 0;
int frquency1 = 1;
if (Convert.ToString(row["RelativeFactor"]) != "")
minute = Convert.ToInt32(row["RelativeFactor"]);
if (Convert.ToString(row["Tfrquency"]) != "")
frquency1 = Convert.ToInt32(row["Tfrquency"]);
tsDueTime = new TimeSpan(frquency1, minute, 0);
tsPeriod = new TimeSpan(frquency1, 0, 0);
}
else
{
tsDueTime = new TimeSpan();
tsPeriod = new TimeSpan();
}
}
我已通过频率设置定时器和同时启动定时器的数量。
我的o/p:
我让这个o/p定时器在08秒变化时启动,然后切换到09秒
现在我的问题是,为什么所有计时器都没有按精确的时间执行
有什么解决方案吗?在每一秒或更长的时间间隔过后,以下尝试将计时器与系统时钟重新同步
// add these fields
private TimeSpan[] _interval;
private DateTime[] _startTime;
// when you create timer1 array, need to initialize the above arrays
int len = timer1.Length;
_interval = new TimeSpan[len];
_startTime = new DateTime[len];
// change SetTimers method as follows;
public void SetTimers(int timer, DataRow row)
{
TimeSpan dueTime;
TimeSpan interval;
SetTimeIntervals(row, out dueTime, out interval);
_interval[timer] = interval;
_startTime[timer] = DateTime.Now + dueTime;
object[] obj = new object[2]{row, timer};
timer1[timer] = new System.Threading.Timer(databaseTrensfer, obj, dueTime, interval);
}
// change databaseTrensfer method as follows
public void databaseTrensfer(object state)
{
object[] obj = (object[])state;
DataRow row = (DataRow)obj[0];
string alarmType = Convert.ToString(row["EBase"]);
if (alarmType != "Milisecond" && alarmType != "Once")
{
int timer = (int)obj[1];
DateTime dt = DateTime.Now;
long elapsedMs = Convert.ToInt64((dt - _startTime[timer]).TotalMilliseconds);
long intervalMs = Convert.ToInt64(_interval[timer].TotalMilliseconds);
long remainder = elapsedMs % intervalMs;
if (remainder != 0L)
{
timer1[timer].Change(_interval[timer] - TimeSpan.FromMilliseconds(remainder), _interval[timer]);
}
}
//code
}
可能的副本可能会让你有更多的想法。你为什么不使用
秒表
类?
// add these fields
private TimeSpan[] _interval;
private DateTime[] _startTime;
// when you create timer1 array, need to initialize the above arrays
int len = timer1.Length;
_interval = new TimeSpan[len];
_startTime = new DateTime[len];
// change SetTimers method as follows;
public void SetTimers(int timer, DataRow row)
{
TimeSpan dueTime;
TimeSpan interval;
SetTimeIntervals(row, out dueTime, out interval);
_interval[timer] = interval;
_startTime[timer] = DateTime.Now + dueTime;
object[] obj = new object[2]{row, timer};
timer1[timer] = new System.Threading.Timer(databaseTrensfer, obj, dueTime, interval);
}
// change databaseTrensfer method as follows
public void databaseTrensfer(object state)
{
object[] obj = (object[])state;
DataRow row = (DataRow)obj[0];
string alarmType = Convert.ToString(row["EBase"]);
if (alarmType != "Milisecond" && alarmType != "Once")
{
int timer = (int)obj[1];
DateTime dt = DateTime.Now;
long elapsedMs = Convert.ToInt64((dt - _startTime[timer]).TotalMilliseconds);
long intervalMs = Convert.ToInt64(_interval[timer].TotalMilliseconds);
long remainder = elapsedMs % intervalMs;
if (remainder != 0L)
{
timer1[timer].Change(_interval[timer] - TimeSpan.FromMilliseconds(remainder), _interval[timer]);
}
}
//code
}