1
2
如果你试图按照汉斯的建议计算墙壁时间的差异,要小心。你不能只使用
即使指定了本地种类,也不考虑DST。
如果你要采取这种方法,你必须使用
您可能需要收集这样的输入:
然而 -设置一个定时器运行这么长时间可能不是一个好主意。时钟不仅可能因用户或系统时间同步而更改,而且应用程序或系统可能会关闭或重新启动。此外,如果你有很多这样的任务,你最终可能会因为无所事事而消耗大量资源。 一个想法是保留一份下次开火事件的清单。在您的应用程序中,您会启动一个短暂的轮询计时器(比如每分钟一次左右),并将当前时间与列表中的值进行比较,以了解是否真的需要做任何事情。 另一个想法是稍微改变一下。不进行短轮询,而是对列表进行排序,并设置一个延迟时间,直到下一个事件,最大延迟时间(可能是一个小时)。同样,当计时器启动时,您可以查看是否有什么事情要做,或者是否需要设置另一个计时器延迟。您必须在应用程序启动时以及计划新事件时运行此程序。
对于这两种方法中的任何一种,您都应该使用
如果所有这些听起来太复杂,那么您可以尝试一个预先构建的解决方案,例如 Quartz.net 。特别是,请阅读 this section of their FAQ . 关于你的第一个和第三个要点,我完全同意——但这永远不会发生。即使发生了,我们仍然需要考虑它发生的多年历史。如果你还没看 this video 已经,你应该。 |
2
1
SystemEvents类已经提供了自己的隐藏窗口和调度程序循环,如果您自己不提供的话。它可能看起来很神奇 知道 你有一个,但它符合Windows编程中一个既定的合同。它在用于添加事件处理程序的线程上使用Thread.GetApartmentState()。它返回STA,就像它在任何GUI应用程序中所做的那样,然后它相信您的程序实现了STA合约并启动了一个消息循环,SystemEvents不会做任何特殊的事情。 如果它返回MTA,就像在控制台模式的应用程序或服务中一样,那么它会假设你的程序没有调度程序循环,并像MTA承诺的那样支持线程,并启动一个新线程。您可以在调试器的Debug+Windows+Threads窗口中看到该线程,该线程的名称为“.NET SystemEvents”。该线程创建了一个隐藏窗口并启动一个循环,相当于Application.Run()。您可以使用Spy++看到该窗口,其名称为“.NET BroadcastEventWindow.xxxx”。 值得注意的是,这种行为是许多GUI程序严重失败的原因,通常是在GUI应用程序中的UserPreferenceChanged事件上,通常是用户解锁工作站时。当程序在非STA的工作线程上创建启动屏幕时,就会发生这种情况。SystemEvents假定程序需要帮助,并创建该帮助线程。它现在在错误的线程上触发事件,该程序使用该线程来更新其UI。如果它是一个STA线程,但该线程被允许退出,那么它也会出错。SystemEvents试图在一个不再存在的线程上激发事件,如果失败,则返回到TP线程。这在GUI应用程序中是非常非常糟糕的,死锁是一种常见的结果。 当然,在您的情况下,您非常喜欢SystemEvents类的工作方式,您真的想要那个辅助线程,这样您就不必自己编写了。请记住,TimeChanged事件在一个完全任意的线程上触发,该线程与服务启动的任何线程都无关,因此当然需要正确的互锁。你自己的btw也有同样的问题。 一定要考虑简单的解决方案。你只需要根据明天的挂钟时间和今天的时间差来计算计时器的间隔。换句话说,绝对时间,而不是增量。如果它跨越夏令时变化,将产生23或25个小时。 |
3
0
我找到了我的解决方案,尽管它可能不是Windows服务的最佳解决方案。
我现在使用
这个问题的答案帮助我在Windows服务中实现了消息循环: https://stackoverflow.com/a/9807963/777985 如果有人在不需要这样的消息循环的情况下得到了答案,我会接受的! |
AryA Derakhshan · 在指定的时间重复循环 2 年前 |
user8105388 · If语句不与计时器一起工作 6 年前 |
Don · 无限循环崩溃,但不在更新函数中 6 年前 |
user9769106 · 绘制形状C的路径# 6 年前 |
SPlatten · MSVC 2008更好的时机? 6 年前 |