如何检测何时可以安全升级我的 windows 服务?
How can I detect when it is safe to upgrade my windows service?
我有一个 windows 服务可以轮询数据库并根据它找到的记录执行操作。
我想设置 Azure Devops 以自动部署对此服务的升级。
为了部署升级,我需要停止服务。
有什么方法可以判断这是否会中断处理?
在我的发布管道中,通过命令任务,我使用
sc stop MyService
[更新]
这是我的简化代码
static class Program
{
static void Main()
{
ServiceBase.Run(new ServiceBase[] { new Hoster() });
}
}
public sealed class Hoster : ServiceBase
{
private IMyEngine _engine;
private readonly EventHandler<EngineProgressEventArgs> _progressHandler;
public Hoster()
{
_progressHandler = TrapEngineProgress;
}
protected override void OnStart(string[] args)
{
try
{
_engine = MyFactory.Create();
_engine.Progress += _progressHandler;
_engine.StartupEngine();
}
catch (Exception ex)
{
_logger.Error("OnStart failed", ex);
}
}
protected override void OnStop()
{
if (_engine == null) return;
_engine.Dispose();
_engine.Progress -= _progressHandler;
_engine = null;
}
private void TrapEngineProgress(object sender, EngineProgressEventArgs e)
{
switch (e.Type)
{
case ProgressType.Changed:
Trace("Changed: " + e.Filename);
break;
case ProgressType.Created:
Trace("Created: " + e.Filename);
break;
case ProgressType.Trace:
Trace(e.Message);
break;
case ProgressType.Error:
Error(e.Error, e.Message);
break;
}
}
}
当您发出 SC STOP 命令时,您只是在发出 服务停止自身的请求 。当服务收到请求时,它可以立即停止或等到它完成重要任务——无论它想做什么。您的服务尽在掌握。
为避免不当中断,您的服务 "stop workflow" 应如下所示:
- 请求停止服务(通过 SC STOP、NET STOP 等)
- 服务的"listener thread"收到停止请求
- 线程设置一个标志,表明已请求停止并将服务的状态设置为 SERVICE_STOP_PENDING
- "processing thread" 定期检查标志(在方便的时候 — 可能在作业之间)
- 如果设置了标志,处理循环在方便时退出
- 并且由于所有处理都已完成,服务状态设置为 SERVICE_STOPPED 并且整个服务退出。
采用这种方法,您的服务将永远不会在 "bad" 处中断。
我有一个 windows 服务可以轮询数据库并根据它找到的记录执行操作。
我想设置 Azure Devops 以自动部署对此服务的升级。
为了部署升级,我需要停止服务。
有什么方法可以判断这是否会中断处理?
在我的发布管道中,通过命令任务,我使用
sc stop MyService
[更新]
这是我的简化代码
static class Program
{
static void Main()
{
ServiceBase.Run(new ServiceBase[] { new Hoster() });
}
}
public sealed class Hoster : ServiceBase
{
private IMyEngine _engine;
private readonly EventHandler<EngineProgressEventArgs> _progressHandler;
public Hoster()
{
_progressHandler = TrapEngineProgress;
}
protected override void OnStart(string[] args)
{
try
{
_engine = MyFactory.Create();
_engine.Progress += _progressHandler;
_engine.StartupEngine();
}
catch (Exception ex)
{
_logger.Error("OnStart failed", ex);
}
}
protected override void OnStop()
{
if (_engine == null) return;
_engine.Dispose();
_engine.Progress -= _progressHandler;
_engine = null;
}
private void TrapEngineProgress(object sender, EngineProgressEventArgs e)
{
switch (e.Type)
{
case ProgressType.Changed:
Trace("Changed: " + e.Filename);
break;
case ProgressType.Created:
Trace("Created: " + e.Filename);
break;
case ProgressType.Trace:
Trace(e.Message);
break;
case ProgressType.Error:
Error(e.Error, e.Message);
break;
}
}
}
当您发出 SC STOP 命令时,您只是在发出 服务停止自身的请求 。当服务收到请求时,它可以立即停止或等到它完成重要任务——无论它想做什么。您的服务尽在掌握。
为避免不当中断,您的服务 "stop workflow" 应如下所示:
- 请求停止服务(通过 SC STOP、NET STOP 等)
- 服务的"listener thread"收到停止请求
- 线程设置一个标志,表明已请求停止并将服务的状态设置为 SERVICE_STOP_PENDING
- "processing thread" 定期检查标志(在方便的时候 — 可能在作业之间)
- 如果设置了标志,处理循环在方便时退出
- 并且由于所有处理都已完成,服务状态设置为 SERVICE_STOPPED 并且整个服务退出。
采用这种方法,您的服务将永远不会在 "bad" 处中断。