24小时运行的S3图片同步服务部署后仅执行一次就退出问题
问题原因
- 违反Windows服务生命周期规范:你在
ImageSomeService构造函数中手动调用了OnStart方法,而该方法应由系统服务控制管理器(SCM)在服务注册完成后自动触发。非Debug模式下构造函数调用OnStart后进入死循环,导致后续ServiceBase.Run方法永远无法执行,SCM收不到服务启动成功的通知,超过默认30秒超时时间后会直接终止服务进程。 OnStart方法不能执行长时间阻塞逻辑:SCM要求OnStart必须在短时间内返回,不能直接在其中编写死循环业务逻辑,否则会被判定为启动失败终止进程。- Debug模式无服务管控逻辑:Debug分支下你没有走标准服务运行流程,没有SCM的超时检查机制,所以阻塞的死循环可以一直运行。
修复方案
首先修改ImageSomeService代码,移除构造函数中手动调用OnStart的逻辑,将业务循环放到独立后台线程执行,避免阻塞OnStart返回,参考修改后的代码:
public partial class ImageSomeService : ServiceBase { private Thread _workerThread; private volatile bool _started; // 用volatile保证多线程下变量状态的可见性 public ImageSomeService() { InitializeComponent(); // 移除手动调用OnStart的代码 } protected override void OnStart(string[] args) { _started = true; // 新建后台线程执行业务循环,不阻塞OnStart返回 _workerThread = new Thread(RunWorkerLoop); _workerThread.IsBackground = true; // 设置为后台线程,服务停止时会自动随同进程退出 _workerThread.Start(); } private void RunWorkerLoop() { while (_started) { try { ImageSvcHelper.RunBatch(); System.Threading.Thread.Sleep(10000); } catch (Exception ex) { // 增加全局异常捕获,避免业务代码报错导致线程直接退出 Logger.WriteLine($"批量任务执行出错:{ex.Message} {DateTime.Now}"); // 出错后按需调整重试间隔 System.Threading.Thread.Sleep(30000); } } } protected override void OnStop() { _started = false; // 等待工作线程正常退出,最多等待30秒避免SCM判定服务停止失败 _workerThread?.Join(30000); Logger.WriteLine("服务已正常停止"); } }
内容的提问来源于stack exchange,提问作者user742102
相关产品推荐
相关产品推荐

