问题描述
我有一个使用 python 创建的简单 Windows 服务.我的问题是我不知道完成服务需要多长时间,它可能需要 15 秒,也可能需要 4 个多小时,具体取决于需要对数据做什么.4+ 小时是一种罕见的情况,但我遇到过这种情况.
I have a simple windows service that I created using python. My issue is that I do not know how long the service is going to take to complete, it could have 15 seconds, or it could take 4+ hours depending on what needs to be done with the data. The 4+ hours is a rare case, but I have had situation where this happens.
以下是我一直遵循的 Windows 服务的一般模式.我去掉了所有的逻辑,但这不是问题,只留下了一个虚拟的日志命令.有没有办法防止服务继续或不刷新,直到逻辑部分完成而不是使用超时?
Below is the general pattern that I've been following for windows services. I took out all the logic, but that's not the issue, and only left a dummy logging command. Is there a way to prevent the service to continuing or not refreshing until the logic portion is completed instead of using the timeout?
import win32service
import win32serviceutil
import win32api
import win32con
import win32event
import win32evtlogutil
import os
import sys
import time
import logging
class aservice(win32serviceutil.ServiceFramework):
_svc_name_ = "WeatherService"
_svc_display_name_ = "Weather Service"
_svc_description_ = "Downloads weather data from NOAA and creates maps"
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
import servicemanager
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,(self._svc_name_, ''))
self.timeout = 640000 #640 seconds / 10 minutes (value is in milliseconds)
#self.timeout = 120000 #120 seconds / 2 minutes
# This is how long the service will wait to run / refresh itself (see script below)
while 1:
# Wait for service stop signal, if I timeout, loop again
rc = win32event.WaitForSingleObject(self.hWaitStop, self.timeout)
# Check to see if self.hWaitStop happened
if rc == win32event.WAIT_OBJECT_0:
# Stop signal encountered
servicemanager.LogInfoMsg(self._svc_name_ + " - STOPPED!") #For Event Log
break
else:
#[actual service code between rests]
try:
logging.basicConfig(filename=r"c:\temp\example.log",level=logging.DEBUG,
format='%(asctime)s %(message)s')
logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too')
#file_path = "C:\whereever\my_REAL_py_work_to_be_done.py"
#execfile(file_path) #Execute the script
#inc_file_path2 = "C:\whereever\MORE_REAL_py_work_to_be_done.py"
#execfile(inc_file_path2) #Execute the script
except:
pass
#[actual service code between rests]
def ctrlHandler(ctrlType):
return True
if __name__ == '__main__':
win32api.SetConsoleCtrlHandler(ctrlHandler, True)
win32serviceutil.HandleCommandLine(aservice)
推荐答案
我最终使用了这个模式:http://code.activestate.com/recipes/551780/
I ended up using this pattern: http://code.activestate.com/recipes/551780/
效果很好,但不像魅力.我确实遇到了多处理问题,该过程没有产生实例.对此有何建议?
It works well, but not like a charm. I do have issues with multiprocessing the process is not spawning the instances. Suggestions on That?
请继续发布您的答案,我想看看大家的解决方案,因为 win32api 可能很难使用.
Please continue to post your answers, I would like to see everyone's solutions because the win32api can be hard to work with.
谢谢大家
这篇关于长时间运行进程的超时和 Windows 服务 (Python)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!