如何在每秒的顶部运行计时器? (当毫利斯 = 000 时)

发布于 2024-12-06 21:21:33 字数 659 浏览 2 评论 0原文

在我的应用程序中,我使用了 System.Threading.Timer 的数量并将该计时器设置为每 1 秒触发一次。我的应用程序每 1 秒执行一次线程,但其执行的毫秒数不同。

在我的应用程序中,我使用了 OPC 服务器和 OPC 服务器。 OPC组.一个线程从OPC服务器读取数据(就像一个变量改变它的值&我想每1秒将这一时刻的变化值记录到我的应用程序中) 然后另一个读取此数据的线程每隔 1 秒从第一个线程读取此数据第二个线程用于将数据存储到MYSQL数据库中。 在此过程中,当我从第一个线程读取数据时,我将获得旧的数据值,例如,在这一秒读取 10:28:01.530 的数据,然后我将获得这一秒 10:28:00.260 的信息。我想管理这些线程,第一个线程工作时间为 000 毫秒 &第二个线程的工作时间为 500 毫秒。使用第一个线程在 000 秒处更新数据第二个线程在 500 毫秒读取数据。

我的输出如下:

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

但是,我想要以下结果:

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

如何设置计时器以便回调在“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 & 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"?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

森林很绿却致人迷途 2024-12-13 21:21:33

首先,这是不可能的。即使您要将“事件”安排在比计划提前几毫秒触发的时间,然后在循环中将当前时间的毫秒部分与零进行比较,代码的流量控制也可能会在任何时候被取消。给定的时刻。

您将不得不稍微重新考虑您的设计,而不是依赖于事件何时触发,而是考虑补偿毫秒延迟的算法。

另外,您对 Threading.Timer 不会有太多帮助,如果您定期使用自己的线程,您会有更好的机会:

  • 检查当前时间,看看距离下一个整秒
  • Sleep() 的 时间是多少金额减去“香料”因素
  • 即可完成您必须做的工作。

您将根据获得的结果计算您的“香料”系数 - 睡眠是提前还是晚于计划完成。

如果您要提供有关您明显需要在恰好零毫秒内发生事件的更多信息,我可以帮助您摆脱该要求。

华泰

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

夏见 2024-12-13 21:21:33

我想说这是不可能的。您必须了解切换 cpu 上下文需要时间(如果其他进程正在运行,您必须等待 - cpu shelduler 正在工作)。每个 CPU 时钟周期都需要一些时间,因此同步到 0 毫秒是不可能的。也许通过设置进程的高优先级,您可以接近 0,但您永远无法实现它。

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.

话少情深 2024-12-13 21:21:33

恕我直言,不可能真正让计时器精确地每 1 秒(毫秒)触发一次 - 即使在硬核汇编器中,这在普通 Windows 机器上也是一项非常艰巨的任务。

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.

浅忆流年 2024-12-13 21:21:33

我认为首先您需要做的是:为计时器设置正确的 dueTime 。我是这样做的:
dueTime = 1000 - DateTime.Now.毫秒 + X;其中 X - 为准确性服务,您需要通过测试来选择它。然后 Threading.Timer 每次都会在 CLR 线程池中的线程上运行,并且测试显示 - 该线程每次都是不同的。创建线程会减慢计时器的速度,因此您可以使用 WaitableTimer,它始终在同一线程上运行。您可以使用 Thread.Sleep 方法来代替 WaitableTimer:

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
}

它比计时器工作得更快。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文