无法将 asyncio 与 pywin32 一起使用来创建 Windows 服务

问题描述 投票:0回答:1

我正在使用 pywin32 创建 Windows 服务。

问题是每当我调用

asyncio
asyncio.run()
asyncio.ensure_future()
asyncio.get_event_loop()
asyncio.ProactorEventLoop()
函数时,我都会得到一个
ValueError: set_wakeup_fd only works in main thread

Python版本:3.8.8

执行为:

python test.py install
,然后
python test.py start
。发现错误在
C:/xxx/errorLogs2.txt

代码:

import socket

import win32serviceutil

import servicemanager
import win32event
import win32service
import asyncio

class Test(win32serviceutil.ServiceFramework):
    _svc_name_ = 'testService'
    _svc_display_name_ = 'Test Service'
    _svc_description_ = 'Test Service Description'

    @classmethod
    def parse_command_line(cls):
        win32serviceutil.HandleCommandLine(cls)

    def __init__(self, args):
        win32serviceutil.ServiceFramework.__init__(self, args)
        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
        socket.setdefaulttimeout(60)

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.hWaitStop)

    def SvcDoRun(self):
        try:
            l = asyncio.get_event_loop() # Fails here
            servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                                servicemanager.PYS_SERVICE_STARTED,
                                (self._svc_name_, ''))
        except Exception as e:
            with open('C:/xxx/errorLogs2.txt', 'a') as f:
                f.write(str(e) + '\n')


if __name__ == '__main__':
    Test.parse_command_line()
python windows-services python-asyncio pywin32
1个回答
0
投票

我在尝试连接到 Azure 事件中心(在后台使用 asyncio)的服务时遇到了同样的问题。每次进程尝试连接到事件中心时都会失败并显示

ValueError: set_wakeup_fd only works in main thread

我向服务添加了一些日志记录,以确保它不会尝试从不同的线程启动连接,但日志都表明该服务正在运行

MainThread

在偶然发现this页面后,我终于找到了解决方案。

我将这一行添加到我的代码中,一切都开始按预期工作。

asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())

虽然我不完全理解为什么这个解决方案有效,但我相信它与默认策略

WindowsProactorEventLoopPolicy
使用I/O完成端口有关,这可能会导致问题。

我也不确定为什么使用默认事件循环策略在使用

python -m serviceName debug
运行服务时有效,但在使用
python -m serviceName start
运行服务时不起作用。

© www.soinside.com 2019 - 2024. All rights reserved.