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)