需要增加窗口服务超时时间。

7
我在启动我的Windows服务时遇到了问题...由于OnStart()事件的负载很大,我的服务会爬取数据,将其保存到数据库并发送电子邮件。因此,我的服务需要增加启动时间,因为默认超时时间为30秒...当我遇到以下异常时,我意识到我的服务需要额外的启动时间:
"Could not start the MyName service on Local Computer. Error 1053: The service did not respond to the start or control request in a timely fashion."
请帮忙解决这个问题...提前感谢。

3
XY 问题。移除 OnStart() 事件的大负荷。将冗杂的内容线程化。 - Martin James
我在你的问题中找不到足够的信息来帮助你。你可以考虑调试问题,因为可能有太多的答案。 - SQLMason
先生,实际上,当我在Visual Studio 2010中调试我的服务时,它可以正常工作。但是,当我创建exe文件并将其安装在我的系统上,并转到任务管理器启动我的服务时,会出现超时异常。这是我的问题。现在我通过谷歌搜索发现,我需要增加默认启动时间30秒。 - user2499974
5个回答

11
我意识到当我遇到下面这个异常时,我的服务需要额外的时间来启动。
constructor/start 上运行长时间任务不是好的做法,你应该在一个单独的线程上启动你的长时间任务。服务启动应该是即时的,不应该挂起。
然而如果你仍然想要这样做,可以尝试。
ServiceBase.RequestAdditionalTime(4000); // add 4 seconds

MSDN

RequestAdditionalTime方法旨在由已重写的OnContinue、OnPause、OnStart或OnStop方法调用,以请求挂起操作的额外时间,以防止服务控制管理器(SCM)将服务标记为未响应。如果挂起的操作不是继续、暂停、启动或停止,则会引发InvalidOperationException。


那我需要在 OnStart()、OnPause()、OnStop() 和 OnContinue() 事件中添加 ServiceBase.RequestAdditionalTime(4000) 吗? - user2499974
无论何时您需要增加默认超时时间。在您的情况下,您需要在启动时增加超时时间。但再次强调,这不是一个好的做法。 - Ehsan
@user2499974:你不想开一个新线程吗?那是正确的解决方案。 - Jay Sullivan

4

建议将长时间运行的操作放在一个线程中执行。

protected override void OnStart(string[] args)
{
  Thread thWorker = new Thread(new ThreadStart(
    delegate
    {
       // Do your long operations here
    }
  ));
  thWorker.Start();
}

在这里你必须小心,因为如果委托抛出异常,它将被吞噬而不是停止/崩溃服务,而你实际上可能希望知道服务没有工作,而不是它“运行”,但实际上什么也没做或者不能正常工作。 - deadlydog
默认情况下,侧线程中抛出的未处理异常会终止进程。例如,请参见此讨论:https://stackoverflow.com/a/17203553/717732 - quetzalcoatl

2
据我所知,这个硬限制的存在正是为了防止服务进行这种滥用行为 :)
让你的长时间运行的任务在服务启动外运行。优雅地处理停止服务的情况,然后,如果需要,可以在任务完成时自动停止服务。没有必要在启动时做所有事情。

1

您考虑过使用任务并行库吗?这个例子是VB.Net的,但是您可以理解:

Imports System.Threading.Tasks

Public Class Service1

    Private tasks As New List(Of Task)

    Protected Overrides Sub OnStart(ByVal args() As String)
        tasks.Add(Task.Factory.StartNew(Sub() DoWork()))
    End Sub

    Private Sub DoWork()
        ' Do long running work
    End Sub

    Protected Overrides Sub OnStop()
        Task.WaitAll(tasks.ToArray())
    End Sub

End Class

0

为了调试服务的OnStart(它可能是一个“长时间运行的任务”),我使用以下代码:

    Protected Overrides Sub OnStart(ByVal args() As String)
 #If CONFIG = "Debug" Then
        ' 2 minutes before timeout
        Me.RequestAdditionalTime(2 * 60 * 1000)
        Debugger.Launch()
 #End If
.
.
.
    End Sub

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接