繁体   English   中英

Windows服务中System.Threading.Timers的准确性

[英]Accuracy of the System.Threading.Timers in windows service

我已经在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:

2011-08-22 13:42:08.0
2011-08-22 13:42:18.0
2011-08-22 13:42:28.0
2011-08-22 13:42:38.15
.
.
.
2011-08-22 14:28:38.984
2011-08-22 14:28:48.984
2011-08-22 14:28:59.15
2011-08-22 14:29:09.15
2011-08-22 14:29:19.15
.
.
2011-08-22 15:14:59.953
2011-08-22 15:15:09.968
2011-08-22 15:15:19.968

我让这个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      
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM