在 Windows 服务中执行冗长的初始化

发布于 2024-09-06 05:23:50 字数 61 浏览 2 评论 0原文

当 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 技术交流群。

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

发布评论

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

评论(5

少女净妖师 2024-09-13 05:23:50

您可以使用 BackgroundWorker 执行冗长的操作以响应 Service.Start 事件。

ServiceBase 派生类的 OnStart() 方法中执行此操作非常简单。 MSDN 上还有一个合理的 很好的示例

protected override void OnStart(string[] args)
{
    var worker = new BackgroundWorker();
    worker.DoWork += DoSomeLongOperation;

    worker.RunWorkerAsync();
}

private void DoSomeLongOperation(object sender, DoWorkEventArgs e)
{
   // do your long operation...
}

请注意,您还可以订阅 ProgressChangedRunWorkerCompleted 事件,以便您可以向服务控制管理器通知您的进度和启动成功(或失败)。

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 your ServiceBase-derived class. There's also a reasonable good example on MSDN.

protected override void OnStart(string[] args)
{
    var worker = new BackgroundWorker();
    worker.DoWork += DoSomeLongOperation;

    worker.RunWorkerAsync();
}

private void DoSomeLongOperation(object sender, DoWorkEventArgs e)
{
   // do your long operation...
}

Note that you can also subscribe to the ProgressChanged and RunWorkerCompleted events, so that you can inform the service control manager of your progress and startup success (or failure).

寄与心 2024-09-13 05:23:50

我在 Windows 服务中也遇到过这个问题。我认为你必须将初始化逻辑保持在30秒以内,否则Windows服务管理器将停止服务。

我所做的很简单。我创建了一个方法,其中放置了需要执行的所有繁重逻辑,然后创建了一个计时器,该计时器将在 20 秒后滴答并执行该方法。因此服务将启动,然后创建计时器,以 20 秒的间隔对其进行初始化,然后完成初始化。 20 秒后,计时器将滴答作响并启动应用程序的业务逻辑。当然,您可以指定您想要的任何时间间隔。

您应该将计时器声明为类的参数:

public partial class YourService: ServiceBase
{
   System.Timers.Timer tmrOnStart;

然后在 OnStart 方法中初始化计时器

protected override void OnStart(string[] args)
{
    //set the interval to 20 seconds
    tmrOnStart = new Timer();
    tmrOnStart.Interval = 20000;
    tmrOnStart.Enabled = true;
    tmrOnStart.AutoReset = false;
    tmrOnStart.Elapsed += new ElapsedEventHandler(tmrOnStart_Elapsed);
    tmrOnStart.Start();
}

当计时器触发 Elapsed 事件时,它将执行此方法:

void tmrOnStart_Elapsed(object sender, ElapsedEventArgs e)
{
    heavyBusinessLogicMethod();
}

并且您必须将逻辑放在 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:

public partial class YourService: ServiceBase
{
   System.Timers.Timer tmrOnStart;

Then initialize the timer in the OnStart method

protected override void OnStart(string[] args)
{
    //set the interval to 20 seconds
    tmrOnStart = new Timer();
    tmrOnStart.Interval = 20000;
    tmrOnStart.Enabled = true;
    tmrOnStart.AutoReset = false;
    tmrOnStart.Elapsed += new ElapsedEventHandler(tmrOnStart_Elapsed);
    tmrOnStart.Start();
}

When the timer will trigger the Elapsed event, it will execute this method:

void tmrOnStart_Elapsed(object sender, ElapsedEventArgs e)
{
    heavyBusinessLogicMethod();
}

And you would have to put your logic in the heavyBusinessLogicMethod method.

酷遇一生 2024-09-13 05:23:50

我也必须这样做:我在启动时生成一个线程,该线程执行所有初始化工作,并在完成时将私有“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.

So尛奶瓶 2024-09-13 05:23:50

我们通常使用一个简单的定时器来实现此功能。我们将在服务 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.

朮生 2024-09-13 05:23:50

最好的实用方法是创建一个工作线程。

一般来说,存在另一种记录的方式,我可以在非托管代码的示例中进行解释。在初始化期间,Windows 服务有很短的时间来执行此操作。这个时间可以在注册表中的某个地方更改。如果服务需要更多,可以

通过 dwCurrentState=SERVICE_START_PENDING 调用 SetServiceStatusSERVICE_STATUS 的一些 dwCheckPointdwWaitHint 结构体已填充,以便 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 with dwCurrentState=SERVICE_START_PENDING some dwCheckPoint and dwWaitHint, of SERVICE_STATUS struct filled so that dwWaitHint 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 the SetServiceStatus function with either an incremented dwCheckPoint value or a change in dwCurrentState. See description of dwWaitHint on http://msdn.microsoft.com/en-us/library/ms685996(VS.85).aspx.

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