开发者

How to run a timer at the TOP of each second? (when millis = 000)

In my application, I have used the number of System.Threading.Timer and set this timer to fire every 1 second. My application execute the thread at every 1 second but it execution of the millisecond is different.

In my application i have used the OPC server & OPC group .one thread reading the data from the OPC server (like one variable changing it's value & i want to log this moment of the changes values into my application every 1 s) then another thread to read this data read this data from the first thread every 1s & second thread used for store data into the MYSQL database . in this process when i will read the data from the first thread then i will get the old data values like , read the data at 10:28:01.530 this second then i will get the information of 10:28:00.260 this second.so i want to mange these threads the first thread worked at 000 millisecond 开发者_JAVA百科& second thread worked at 500 millisecond. using this first thread update the data at 000 second & second thread read the data at 500 millisecond.

My output is given below:

10:28:32.875
10:28:33.390
10:28:34.875
....
10:28:39.530
10:28:40.875

However, I want following results:

10:28:32.000
10:28:33.000
10:28:34.000
....
10:28:39.000
10:28:40.000

How can the timer be set so the callback is executed at "000 milliseconds"?


First of all, it's impossible. Even if you are to schedule your 'events' for a time that they are fired few milliseconds ahead of schedule, then compare millisecond component of the current time with zero in a loop, the flow control for your code could be taken away at the any given moment.

You will have to rethink your design a little, and not depend on when the event would fire, but think of the algorithm that will compensate for the milliseconds delayed.

Also, you won't have much help with the Threading.Timer, you would have better chance if you have used your own thread, periodically:

  • check for the current time, see what is the time until next full second
  • Sleep() for that amount minus the 'spice' factor
  • do the work you have to do.

You'll calculate your 'spice' factor depending on the results you are getting - does the sleep finishes ahead or behind the schedule.

If you are to give more information about your apparent need for having event at exactly zero ms, I could help you get rid of that requirement.

HTH


I would say that its impossible. You have to understand that switching context for cpu takes time (if other process is running you have to wait - cpu shelduler is working). Each CPU tick takes some time so synchronization to 0 milliseconds is impossible. Maybe with setting high priority of your process you can get closer to 0 but you won't achive it ever.


IMHO it will be impossible to really get a timer to fire exactly every 1sec (on the milisecond) - even in hardcore assembler this would be a very hard task on your normal windows-machine.


I think first what you need to do: is to set right dueTime for a timer. I do it so: dueTime = 1000 - DateTime.Now.Milliseconds + X; where X - is serving for accuracy and you need select It by testing. Then Threading.Timer each time It ticks running on thread from CLR thread pool and, how tests show - this thread is different each time. Creating threads slows timer, because of this you can use WaitableTimer, which always will be running at the same thread. Instead of WaitableTimer you can using Thread.Sleep method in such way:

Thread.CurrentThread.Priority = Priority.High; //If time is really critical
Thread.Sleep (1000 - DateTime.Now + 50); //Make bound = 1s
while (SomeBoolCondition)
{
  Thread.Sleep (980); //1000 ms = 1 second, but something ms will be spent on exit from Sleep
  //Here you write your code
}

It will be work faster then a timer.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜