在不阻止服务控制管理器的情况下启动Windows服务(或暂停恢复)时进行冗长初始化的最佳方法是什么?
答案 0 :(得分:9)
您可以使用BackgroundWorker
执行冗长的操作以响应Service.Start事件。
在OnStart()
派生类的ServiceBase
方法中这样做很容易。还有一个合理的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...
}
请注意,您还可以订阅ProgressChanged
和RunWorkerCompleted
事件,以便您可以通知服务控制管理员您的进度和启动成功(或失败)。
答案 1 :(得分:2)
我也遇到过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方法中。
答案 2 :(得分:1)
我也必须这样做:我在启动时生成一个执行所有初始化的线程,并在完成后将私有'isInitialized'设置为true。该服务定期执行操作(即,在计时器上),如果isInitialized未设置为true,则不会启动这些操作。
答案 3 :(得分:1)
我们通常使用简单的计时器来实现此功能。我们将在服务OnStartup中设置计时器,让服务响应服务控制管理器,然后在几秒钟后启动计时器。根据需要做什么,该过程可以在单独的线程中进行。如果需要定期进行此过程,则可以重复使用计时器。
答案 4 :(得分:0)
最好的实用方法是创建一个工作线程。
一般存在另一种记录方式,我可以解释非托管代码的例子。在初始化期间,Windows服务只有很短的时间来完成此操作。这个时间可以在注册表中的某处更改。如果服务需要更多,如果可以调用
SetServiceStatus
dwCurrentState=SERVICE_START_PENDING
dwCheckPoint
和dwWaitHint
SERVICE_STATUS
结构填充为dwWaitHint
,以便SetServiceStatus
为待定所需的估计时间以毫秒开始操作。在指定的时间量过去之前,服务应该使用递增的dwCheckPoint
值或dwCurrentState
的更改来dwWaitHint
函数进行下一次调用。请参阅http://msdn.microsoft.com/en-us/library/ms685996(VS.85).aspx上{{1}}的说明。