Windows服务多线程异常:启动报Error1053,无法周期性检测设备
Windows服务错误1053快速修复方案(适配设备连接逻辑)
问题根源
Windows服务要求OnStart方法必须在30秒内完成返回,你的StartDeviceConnections方法包含无限循环(goto+Thread.Sleep),如果直接在服务启动线程中执行,会导致启动线程被阻塞,无法及时响应系统的启动请求,触发错误1053。
快速修复(无需大重构)
核心思路是把循环逻辑移到后台线程执行,让OnStart快速返回,同时保留原有业务逻辑:
1. 修改服务的OnStart方法
protected override void OnStart(string[] args) { // 将设备连接循环逻辑丢到后台线程,让OnStart立刻返回 ThreadPool.QueueUserWorkItem(_ => StartDeviceConnections()); }
2. 调整StartDeviceConnections方法(用while替代goto,逻辑不变)
private static void StartDeviceConnections() { Thread th = Thread.CurrentThread; th.Name = "MainThread"; var threads = new List<Thread>(); var onlyOffline = false; setupDeviceTimer(); setupSyncLogsTimer(); // 用while(true)替代goto,逻辑完全一致,可读性更好 while (true) { try { var objDevice = new DeviceService(); objDevice.UpdateDeviceStatus(0, DeviceStatuses.Offline, "updateAll"); var devices = new DeviceService().GetOfflineIRISDevices(); if (devices != null && devices.Count > 0) { foreach (var device in devices) { Thread childThread = new Thread(() => DeviceSyncManager(device)); childThread.Start(); childThread.Name = device.ipAddress; threads.Add(childThread); Thread.Sleep(1000); } } } catch (Exception e) { // 务必添加日志记录,否则异常无法排查 // 示例:Log.Error(e, "设备连接循环执行出错"); } // 等待下一轮检测周期 Thread.Sleep(MinutesToCheckDeviceStatusAgain * 60 * 1000); onlyOffline = true; } }
关键说明
- 原方法的
async void是多余的:代码全程用Thread.Sleep同步阻塞,没有用到真正的异步操作,去掉async不影响功能。 - 后台线程执行循环:通过
ThreadPool.QueueUserWorkItem把循环逻辑放到后台线程,让OnStart在毫秒级返回,完全符合Windows服务的启动超时要求。 - 保留原有业务逻辑:没有修改检测离线设备、创建子线程的核心逻辑,只是调整了执行载体,满足时间紧张的需求。
额外建议(可选,不影响当前修复)
- 线程管理:
threads列表会持续添加新线程,建议在每次循环开始前清理已终止的线程,避免内存泄漏:threads.RemoveAll(t => !t.IsAlive); - 服务停止逻辑:添加全局
bool _isServiceStopping变量,在OnStop方法中设置为true,循环中判断该变量,实现优雅终止:while (!_isServiceStopping)
内容的提问来源于stack exchange,提问作者Abdul Hanan
相关产品推荐
相关产品推荐

