2016-01-27 2 views
1

Если у меня есть следующие:Закрытие подзадачи запущен с 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() отменяется?

ответ

1

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() обернут в задаче и будет отменен автоматически, если родительская задача должна быть отменена.


EDIT

Вот простой пример сопрограммы управляет выполнением другого:

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() делается.

+0

Я предполагаю, что я пропустил это требование - я также хотел бы вызвать любые исключения, вызванные подзадачей, которые будут выбрасываться в текущую задачу. – Eric

+0

@Eric. Тогда почему бы просто не использовать 'await task' или' await foo() ' ? – Vincent

+0

Потому что я хочу посмотреть другие вещи и отменить задачу раньше – Eric

Смежные вопросы