Web Analytics
yangyang

码农兼一个普普通通小青年

All Posts in 2025.6


Windows服务“伪运行”之谜:从一个时间同步服务的失灵谈起

本文通过一个时间同步服务的具体案例,深入探讨了Windows服务在“快速启动”模式下出现的“伪运行”问题。该问题的典型症状是:服务设置为自动启动,在“关机”再开机后,其状态显示为“正在运行”,却没有执行其OnStart方法中的关键启动任务(如首次时间同步)。文章剖析了此现象的根本原因在于Windows的快速启动机制。该机制通过休眠并恢复系统内核及服务进程来加速开机,这个过程会完全跳过OnStart方法,导致服务从一个过时的、无效的内存状态中“假醒”,成为“僵尸服务”。为解决此问题,文章提供了一套完整的排查与解决方案。首先,介绍了如何通过正确配置Windows事件日志来进行有效诊断,并指出了创建事件源的权限要点。其次,说明了如何通过禁用快速启动来快速验证问题根源。最终,文章给出了最健壮的根本性解决方案:在C#服务代码中重写OnPowerEvent方法,使其能够响应系统的Suspend …

Windows Service Fast Startup OnStart OnPowerEvent ResumeSuspend Hybrid Shutdown Event Log Service Troubleshooting

不止于值:解析.NET中“赋值即触发”的状态驱动事件模式

即便是给一个对象的属性赋上与它当前完全相同的值,相关的“已更改”(XXXChanged)事件依然被触发了。一个典型的例子就是在使用 System.Data.DataTable 或System.Configuration.ApplicationSettingsBase时。研究源码发现,ApplicationSettingsBase 和 DataTable 的“赋值即触发”行为,并非缺陷,而是.NET框架中一个优雅且实用的状态驱动事件模式的体现。它将数据容器从简单的值存储器提升为强大的状态机,极大地简化了数据持久化和同步的复杂性。它选择牺牲微不足道的判断性能,来换取核心功能(状态跟踪)的绝对可靠性。理解了其“关注状态,而非价值”的核心思想,并洞悉其源码实现后,我们就能根据实际场景,明智地选择是利用还是“修正”这一行为,从而编写出更健壮、更高效的.NET应用程序。 …

ApplicationSettingsBase PropertyChanged

使用NTP协议实现时间同步客户端和授时服务端

在之前写了两篇关于NTP的文章,一篇是使用NTP协议实现本地时间跟NTP授时服务器进行同步介绍了NTP协议的原理,另一篇是实现一个时间同步客户端NTPClock介绍了使用WPF编写一个模仿NTPClock的时间同步的App,因为Windows的自动较时功能不是很完善,所以这个应用我自己使用了很长时间。 在这篇文章里,我准备将前面两篇文章总结一下,对一些方法进行重构,另外实现一个利用NTP来实现授时的服务端,以完善整个功能。一般的我们都是使用一些公开的NTP授时服务地址,比如"time.windows.com"、"pool.ntp.org"等来获取时间,这有一些限制: 必须要求这个服务器能够访问和解析这些授时服务器地址,这在有些机房的内网计算机上其实是无法满足条件的。 这些公开的NTP授时服务器大多有请求频率限制,如果请求次数多过或过快,可能会请求失败。 有时候,我们有自己的GPS接收装置 …

NTP