在 Windows 服务中执行冗长的初始化
当 Windows 服务启动(或从暂停中恢复)时执行一些冗长的初始化而不阻止服务控制管理器的最佳方法是什么?
What's the best way to do some lengthy initialization when a Windows service starts up (or resumes from being paused) without blocking the Service Control Manager?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可以使用
BackgroundWorker
执行冗长的操作以响应 Service.Start 事件。在
ServiceBase
派生类的OnStart()
方法中执行此操作非常简单。 MSDN 上还有一个合理的 很好的示例。请注意,您还可以订阅
ProgressChanged
和RunWorkerCompleted
事件,以便您可以向服务控制管理器通知您的进度和启动成功(或失败)。You can use a
BackgroundWorker
to perform your lengthy operation in response to the Service.Start event.It's easy enough to do so in the
OnStart()
method of yourServiceBase
-derived class. There's also a reasonable good example on MSDN.Note that you can also subscribe to the
ProgressChanged
andRunWorkerCompleted
events, so that you can inform the service control manager of your progress and startup success (or failure).我在 Windows 服务中也遇到过这个问题。我认为你必须将初始化逻辑保持在30秒以内,否则Windows服务管理器将停止服务。
我所做的很简单。我创建了一个方法,其中放置了需要执行的所有繁重逻辑,然后创建了一个计时器,该计时器将在 20 秒后滴答并执行该方法。因此服务将启动,然后创建计时器,以 20 秒的间隔对其进行初始化,然后完成初始化。 20 秒后,计时器将滴答作响并启动应用程序的业务逻辑。当然,您可以指定您想要的任何时间间隔。
您应该将计时器声明为类的参数:
然后在 OnStart 方法中初始化计时器
当计时器触发 Elapsed 事件时,它将执行此方法:
并且您必须将逻辑放在 HeavyBusinessLogicMethod 方法中。
I also had this problem with a Windows Service. I think you have to keep the initialization logic under 30 seconds, otherwise the Windows Service Manager will stop the service.
What I did was quite simple. I created a method where I put all of the heavy logic that needed to be executed and then I created a timer that would tick after 20 seconds and execute that method. So the service would start, then create the timer, initialize it with an interval of 20 seconds and then finish the initialization. After 20 seconds the timer would tick and start the business logic of the application. Of course you can specify whatever interval of time you want.
You should declare the timer as a parameter of the class:
Then initialize the timer in the OnStart method
When the timer will trigger the Elapsed event, it will execute this method:
And you would have to put your logic in the heavyBusinessLogicMethod method.
我也必须这样做:我在启动时生成一个线程,该线程执行所有初始化工作,并在完成时将私有“isInitialized”设置为 true。该服务定期执行操作(即,在计时器上),并且如果 isInitialized 未设置为 true,则不会开始这些操作。
I have to do this as well: I spawn a thread on startup that does all of its initialization and sets a private 'isInitialized' to true when it's finished. The service does actions periodically (ie, on a timer) and won't begin those actions if isInitialized isn't set to true.
我们通常使用一个简单的定时器来实现此功能。我们将在服务 OnStartup 中设置计时器,让服务响应服务控制管理器,然后让计时器在几秒钟后启动进程。该过程可以进入或不进入单独的线程,具体取决于需要完成的操作。如果此过程需要定期发生,则可以重复使用计时器。
We typically use a simple timer to achieve this functionality. We'll set the timer up in the service OnStartup, let the service respond back the Service Control Manager and then have the timer kick off the process after a few seconds. That process can go in a separate thread or not depending on what needs to be done. The timer can be reused if this process needs to happen at regular intervals.
最好的实用方法是创建一个工作线程。
一般来说,存在另一种记录的方式,我可以在非托管代码的示例中进行解释。在初始化期间,Windows 服务有很短的时间来执行此操作。这个时间可以在注册表中的某个地方更改。如果服务需要更多,可以
通过
dwCurrentState=SERVICE_START_PENDING
调用SetServiceStatus
,SERVICE_STATUS 的一些
结构体已填充,以便dwCheckPoint
和dwWaitHint
dwWaitHint
为挂起启动操作所需的估计时间(以毫秒为单位)。在指定的时间过去之前,服务应使用递增的dwCheckPoint
值或更改dwCurrentState
来对SetServiceStatus
函数进行下一次调用。代码>.请参阅 http 上的dwWaitHint
说明://msdn.microsoft.com/en-us/library/ms685996(VS.85).aspx。The best pragmatical way is creating a working thread.
In general exist another documented way, which I can explain on the example of unmanaged code. During initialization a windows service have a small time to do this. This time can be change somewhere in registry. If service need more if can call
SetServiceStatus
withdwCurrentState=SERVICE_START_PENDING
somedwCheckPoint
anddwWaitHint
, ofSERVICE_STATUS
struct filled so thatdwWaitHint
is The estimated time required for a pending start operation in milliseconds. Before the specified amount of time has elapsed, the service should make its next call to theSetServiceStatus
function with either an incrementeddwCheckPoint
value or a change indwCurrentState
. See description ofdwWaitHint
on http://msdn.microsoft.com/en-us/library/ms685996(VS.85).aspx.