关闭使用 asyncio.ensure_future 启动的子任务
Closing subtasks launched with asyncio.ensure_future
如果我有以下情况:
async def foo():
for i in range(10):
print "1"
await asyncio.sleep(1)
async def bar()
t = asyncio.ensure_future(foo())
while not t.done():
print("waiting")
await asyncio.sleep(0.5)
async def baz():
t = asyncio.ensure_future(bar())
await asyncio.sleep(2.5)
t.cancel()
并且 baz()
在一个更大的事件循环中被调用,我如何确保 foo() 被取消?
A try/finally
块将捕获 CancelledError 异常:
task = asyncio.ensure_future(foo())
try:
[...]
finally:
task.cancel() # return False if task is already finished
一些task functions已经处理了子任务的取消:
result = await asyncio.wait_for(foo(), 60.)
result, = await asyncio.gather(foo())
在这两个示例中,foo()
都包含在任务中,如果要取消父任务,则会自动取消。
编辑
这是一个协程控制另一个协程执行的简单示例:
async def control(coro, timeout=1.):
task = asyncio.ensure_future(coro)
while not task.done():
try:
print("The task is not finished yet")
await asyncio.wait([task, asyncio.sleep(timeout)], "FIRST_COMPLETED")
except asyncio.CancelledError:
task.cancel()
return task.result() # Raise task.exception() if any
现在,await control(foo(), 1.)
应该像 await foo()
一样工作(关于取消、异常和结果)除了它每秒打印 The task is not finished yet
直到 foo()
完成。
如果我有以下情况:
async def foo():
for i in range(10):
print "1"
await asyncio.sleep(1)
async def bar()
t = asyncio.ensure_future(foo())
while not t.done():
print("waiting")
await asyncio.sleep(0.5)
async def baz():
t = asyncio.ensure_future(bar())
await asyncio.sleep(2.5)
t.cancel()
并且 baz()
在一个更大的事件循环中被调用,我如何确保 foo() 被取消?
A try/finally
块将捕获 CancelledError 异常:
task = asyncio.ensure_future(foo())
try:
[...]
finally:
task.cancel() # return False if task is already finished
一些task functions已经处理了子任务的取消:
result = await asyncio.wait_for(foo(), 60.)
result, = await asyncio.gather(foo())
在这两个示例中,foo()
都包含在任务中,如果要取消父任务,则会自动取消。
编辑
这是一个协程控制另一个协程执行的简单示例:
async def control(coro, timeout=1.):
task = asyncio.ensure_future(coro)
while not task.done():
try:
print("The task is not finished yet")
await asyncio.wait([task, asyncio.sleep(timeout)], "FIRST_COMPLETED")
except asyncio.CancelledError:
task.cancel()
return task.result() # Raise task.exception() if any
现在,await control(foo(), 1.)
应该像 await foo()
一样工作(关于取消、异常和结果)除了它每秒打印 The task is not finished yet
直到 foo()
完成。