replacing asyncio with concurent.futures



asyncio在我的spyder IDE上导致问题=>我想用concurrent替换它。期货图书馆

如何替换下面只依赖于并发的代码。未来的图书馆asyncio.get_event_loop().run_until_complete(api(message))

确切函数如下

def async_loop(api, message):
return asyncio.get_event_loop().run_until_complete(api(message))

如上所述,您只启动事件循环直到特定任务完成(该任务可能启动也可能不启动或等待其他任务),并阻塞直到它完成。是一个任务的原因是因为它需要使用async函数,这些函数只能在事件循环中运行,并且在运行时,它们可能会启动其他任务或等待其他可等待对象,而在等待期间,事件循环可以执行其他任务。

简而言之,如果不需要在非异步上下文中运行异步任务,则只需:

def async_loop(api, message):
return api(message)

调用api并等待它完成。

真的,就是这样。如果api所做或调用的事情需要异步运行一些任务,而不立即阻塞它们,您将有一些全局执行器,例如

executor = concurrent.Futures.ThreadPoolExecutor()

,它将被用来启动任务:

fut = executor.submit(callable, 'arg1', 'arg2', kwarg1='somevalue')

,当需要任务的结果时,有人会调用:

value = fut.result()

(如果它还没有完成,它会阻塞;如果它没有异常完成,它会返回结果;如果它因异常而结束,它会引发异常)。

当您不再需要executor时,只需在它上调用.shutdown(),它将等待所有未完成的任务完成。就是这样。


作为旁注,您遇到的错误是他们在3.10中弃用get_event_loop()的部分原因(并且从3.7开始不鼓励)。很可能,问题的最简单解决方案(避免切换到线程,因为这意味着您有新的问题)是使用更简单的高级APIasyncio.run(在3.7中引入),它创建一个事件循环,运行其中的任务直到完成,进行合理的清理,然后返回结果:

def async_loop(api, message):
return asyncio.run(api(message))

还有asyncio.get_running_loop函数(这是get_event_loop的确切替代品),当事件循环已经存在时使用(您通常应该意识到;事件循环不会在给定线程中自行出现,所以你应该知道自己是否启动了一个;在这种情况下,你没有,所以asyncio.run是正确的使用)。

最新更新