gpt4 book ai didi

python - 如何为异步生成器提供来自 python.net 的事件

转载 作者:太空宇宙 更新时间:2023-11-03 10:48:55 24 4
gpt4 key购买 nike

我通过 Python for .Net 在 Python 3.6 中使用第三方 .Net 库,它使用 EventHandlers 向我的应用程序提供异步数据,类似于下面的玩具示例:

import clr
from System import Timers

def tock(__, args):
print(args.SignalTime)

timer = Timers.Timer()
timer.Interval = 1000
timer.Elapsed += tock
timer.Enabled = True
while True:
pass

我想将这些数据放入异步生成器中,例如:

import clr
from System import Timers

async def tock(__, args):
yield args.SignalTime

async def main():
result = await tock
print(result)

timer = Timers.Timer()
timer.Interval = 1000
timer.Elapsed += tock
timer.Enabled = True
while true:
result = await timer
print result

显然只是在事件处理函数上抛出 asycyieldawait 计时器不会这样做,但是有没有实现此目的的直接方法?

最佳答案

由于“异步”数据来自另一个线程,因此您需要在 asyncio 和调用 tock 的线程之间建立桥梁。在 asyncio 方面,您需要实现一个异步生成器并使用 async for 循环对其进行迭代。例如(未经测试):

import clr, asyncio
from System import Timers

def adapt_sync_to_async():
# Adapt a series of sync callback invocations to an async
# iterator. Returns an async iterator and a feed callback
# such that the async iterator will produce a new item
# whenever the feed callback is fed one.
loop = asyncio.get_event_loop()
queue = asyncio.Queue()
def feed(item):
loop.call_soon_threadsafe(queue.put_nowait, item)
async def drain():
while True:
yield await queue.get()
return drain, feed

tock, feed_tock = adapt_sync_to_async()

async def main():
async for result in tock():
print(result)

timer = Timers.Timer()
timer.Interval = 1000
timer.Elapsed += lambda _, args: feed_tock(args.SignalTime)
timer.Enabled = True

asyncio.get_event_loop().run_until_complete(main())

关于python - 如何为异步生成器提供来自 python.net 的事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55290397/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com