最近我想在后台运行其他任务的同时运行一些异步任务,但我认为代码不够 Pythonic :
struct NodeLevel{
int level;
BinaryTreeNode * node;
NodeLevel(int val, BinaryTreeNode * x) : level(val), node(x) {}
};
class Solution {
public:
vector<vector<int>> levelOrder(BinaryTreeNode* root) {
queue<NodeLevel> q;
rootLevel = NodeLevel(0, root);
q.push(rootLevel);
/*
do some stuff with the queue
*/
}
};
所以我做了更多 Pythonic :
task = asyncio.create_task(long_task())
await short_task()
await task
这样的东西已经存在了吗?如果不是这样,是否认为它比现有方法更像Pythonic或更不像Pythonic?
答案 0 :(得分:2)
这样的东西已经存在了吗?
目前不行,但这是一个非常有用的主意。该概念的更一般版本将以TaskGroup
和Curio的现有技术启发而以Trio类的形式添加到Python 3.8。
我建议增强使用finally
的实现,以保证即使在异常情况下也可以等待后台任务;例如:
@asynccontextmanager
async def run_in_background(coro):
task = asyncio.create_task(coro)
try:
yield task
finally:
await task
如果不是这样,是否认为它比现有方法更具Python风格?
问题的这一部分显然是基于观点的,但是我想说上下文管理器更具有Python风格,因为它确保在离开该块时已经完成并等待后台任务。它还可以确保后台任务do not pass silently中的异常,这是异步代码中错误的常见来源。
答案 1 :(得分:0)
trio为苗圃对象提供了一种更好的方法:
async with trio.open_nursery() as nursery:
nursery.start_soon(long_task()) # Task will run in background
await short_task()
# Wait for background tasks to finish