Python-asyncio - 使用 timers/threading 终止异步
Python-asyncio - using timers/threading to terminate async
我有一个异步协程,我想使用 timer/thread 终止它。协程基于 aiortc 的 this example。
args = parse_args()
client = Client(connection, media, args.role)
# run event loop
loop = asyncio.get_event_loop()
try:
timer = None
if args.timeout:
print("Timer started")
timer = threading.Timer(args.timeout, loop.run_until_complete, args=(client.close(),))
timer.start()
loop.run_until_complete(client.run())
if timer:
timer.join()
except KeyboardInterrupt:
pass
finally:
# cleanup
loop.run_until_complete(client.close())
这不起作用并引发 RuntimeError('This event loop is already running')
为什么会引发错误?我的猜测是因为循环是 运行 在不同的线程上。但是,创建新循环不起作用,因为它将未来附加到不同的循环。
def timer_callback():
new_loop = asyncio.new_event_loop()
new_loop.run_until_complete(client.close())
接下来,如何使用计时器结束脚本?
这不是我正在寻找的通用解决方案,我向客户端构造函数添加了一个 timeout
变量,并在 client.run()
中添加了 asyncio.sleep(timeout)
这将退出环形。这对我来说已经足够了。
Following that, how can I use a timer to end the script?
您可以调用 asyncio.run_coroutine_threadsafe()
将协程提交给另一个线程中的事件循环 运行:
if args.timeout:
print("Timer started")
timer = threading.Timer(
args.timeout,
asyncio.run_coroutine_threadsafe,
args=(client.close(), loop),
)
timer.start()
但是请注意,由于您使用的是 asyncio,因此您不需要计时器的专用线程,您可以创建一个协程并告诉它在执行某些操作之前等待:
if args.timeout:
print("Timer started")
async def close_after_timeout():
await asyncio.sleep(args.timeout)
await client.close()
loop.create_task(close_after_timeout())
我有一个异步协程,我想使用 timer/thread 终止它。协程基于 aiortc 的 this example。
args = parse_args()
client = Client(connection, media, args.role)
# run event loop
loop = asyncio.get_event_loop()
try:
timer = None
if args.timeout:
print("Timer started")
timer = threading.Timer(args.timeout, loop.run_until_complete, args=(client.close(),))
timer.start()
loop.run_until_complete(client.run())
if timer:
timer.join()
except KeyboardInterrupt:
pass
finally:
# cleanup
loop.run_until_complete(client.close())
这不起作用并引发 RuntimeError('This event loop is already running')
为什么会引发错误?我的猜测是因为循环是 运行 在不同的线程上。但是,创建新循环不起作用,因为它将未来附加到不同的循环。
def timer_callback():
new_loop = asyncio.new_event_loop()
new_loop.run_until_complete(client.close())
接下来,如何使用计时器结束脚本?
这不是我正在寻找的通用解决方案,我向客户端构造函数添加了一个 timeout
变量,并在 client.run()
中添加了 asyncio.sleep(timeout)
这将退出环形。这对我来说已经足够了。
Following that, how can I use a timer to end the script?
您可以调用 asyncio.run_coroutine_threadsafe()
将协程提交给另一个线程中的事件循环 运行:
if args.timeout:
print("Timer started")
timer = threading.Timer(
args.timeout,
asyncio.run_coroutine_threadsafe,
args=(client.close(), loop),
)
timer.start()
但是请注意,由于您使用的是 asyncio,因此您不需要计时器的专用线程,您可以创建一个协程并告诉它在执行某些操作之前等待:
if args.timeout:
print("Timer started")
async def close_after_timeout():
await asyncio.sleep(args.timeout)
await client.close()
loop.create_task(close_after_timeout())