我正在开发一个项目,将 Python APScheduler 作为 Windows 服务运行,结果将保存到文本文件中。我可以毫不费力地安装和启动服务。
我尝试了几种在服务中运行调度程序的方法,最常见和令人沮丧的结果是,当我停止服务时,调度程序的线程继续写入文本文件。我必须重新启动计算机才能杀死线程。
我尝试了“阻塞”和“后台”调度程序,它们的行为相同。
我玩过将 scheduler.shutdown() 移动到不同的地方。我想将它放在服务停止功能中并让调度程序运行,直到服务收到停止命令,然后服务停止功能将处理关闭调度程序。
也许你能指出我正确的方向?这是经过清理的代码,以确保您不必重新启动计算机。
import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
import time
import logging
import configparser
import os
from datetime import datetime
from mysql.connector import errorcode
from apscheduler.schedulers.background import BackgroundScheduler
global FILEPATH
global SERVICE
#Define constants
FILEPATH = os.path.dirname(os.path.realpath(__file__))
SERVICE = 'service.log'
logging.basicConfig(
filename = '%s\\%s' % (FILEPATH, SERVICE),
level = logging.DEBUG,
format = '[Logging Service] %(levelname)-7.7s %(message)s'
)
def hi(text):
logging.info(text)
return
class HelloWorldSvc (win32serviceutil.ServiceFramework):
_svc_name_ = "Logging-Service"
_svc_display_name_ = "Logging Service"
_svc_description_ = "Periodically logs information"
def __init__(self,args):
win32serviceutil.ServiceFramework.__init__(self,args)
self.stop_event = win32event.CreateEvent(None,0,0,None)
socket.setdefaulttimeout(60)
self.stop_requested = False
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.stop_event)
logging.info('Stopping service ...')
self.stop_requested = True
def SvcDoRun(self):
servicemanager.LogMsg(
servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_,'')
)
self.main()
def main(self):
logging.info(' ** Starting Logging Operation ** ')
scheduler = BackgroundScheduler()
scheduler.add_job(hi, 'interval', seconds=5, args=['arg text'])
scheduler.start()
time.sleep(15)
scheduler.shutdown()
time.sleep(10)
logging.info('Ended')
return
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(HelloWorldSvc)