我在服务器上将应用程序作为服务运行,然后我有多个客户端连接到该服务。我在每个客户端 Window 窗体应用程序上显示确切的服务器时间,因此我需要一种机制来检测服务器上的任何时间更改,以便我可以将其发送到客户端进行显示。
查看 MSDN 我发现 SystemEvents.TimeChanged ,我认为我很幸运,因为在使用 Visual Studio 使用下面的代码进行测试时,一切都很好:
SystemEvents.TimeChanged += new EventHandler(SystemEvents_TimeChanged);
static void SystemEvents_TimeChanged(object sender, EventArgs e)
{
//Occurs when user manually changes the time or due to
//daylight saving time. Server will issue its latest time
//to all the clients so time can be adjusted.
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,当我将它作为服务运行时,这个事件永远不会被触发,因为查看 MSDN 上的细则,TimeChanged 事件仅在具有消息泵(也就是它必须有一个运行表单)活动的应用程序中触发。它在 Visual Studio 中工作,因为当我将它作为非服务模式运行时它有一个表单。
我可以通过选中“允许服务与桌面交互”选项来纠正这个问题,但这违背了我尝试将应用程序作为服务运行的目的。
我可以在应用程序中创建一个计时器滴答事件来检查时间变化,假设每 10 秒左右,但这是一个很大的开销,只是为了检查服务器机器上发生的随机时间变化每年两次或 3 次.
那么有人知道在没有消息泵运行的应用程序中工作的时间更改触发的 C# 事件吗?如果 Microsoft 不包含以这种方式工作的事件,我会感到惊讶
谢谢你。
感谢大家的意见,他们确实为我指明了正确的方向。我能够解决我的问题,并且我想将它们放在这里,供以后发现它们有帮助的任何人使用。
因此,在运行服务的主程序中,它必须是 ServiceBase 的子类。
在我的主函数中,我生成了一个单独的线程,如下所示:
new Thread(RunMessagePump).Start();
private void RunMessagePump()
{
Application.Run(new HiddenForm())
}
Run Code Online (Sandbox Code Playgroud)
这个隐藏表单正如它的名字所说,它是一个简单的表单,被其 Intiailaizecomponent() 代码下的 this.ResumeLayout(false) 代码保持隐藏。
在此表单的 FormLoad 事件中,您可以声明任何系统事件。就我而言,我有
private void HiddenForm_Load(object sender,EventArgs e)
{
SystemEvents.timeChanged += new EventHandler(SystemEvents_TimeChanged);
}
Run Code Online (Sandbox Code Playgroud)
瞧,效果非常好,我想我将使用这个表单加载事件来捕获我想在以后使用的任何系统事件。
干杯。