python asyncio - how to wait for a cancelled shielded task?

前端 未结 2 595
陌清茗
陌清茗 2021-02-14 06:03

If I have a coroutine which runs a task which should not be cancelled, I will wrap that task in asyncio.shield().

It seems the behavior of cancel

2条回答
  •  既然无缘
    2021-02-14 06:17

    It would make more sense if asyncio.shield() raised the asyncio.CancelledError after the await-ed task has completed, but obviously there is some other idea going on here that I don't understand.

    asyncio.shield

    • creates a dummy future, that may be cancelled
    • executes the wrapped coroutine as future and bind to it a callback on done to setting a result for the dummy future from the completed wrapped coroutine
    • returns the dummy future

    You can see the implementation here

    What is the proper method to shield a task from cancellation and then wait for it to complete before returning

    You should shield count(5) future

    async def t():
      c_ft = asyncio.ensure_future(count(5))
      try:
        await asyncio.shield(c_ft)
      except asyncio.CancelledError:
        print('This gets called at 3, not 5')
        await c_ft
    
      return 42
    

    or t() future

    async def t():
      await count(5)
      return 42    
    
    async def m():
      ft = asyncio.ensure_future(t())
      shielded_ft = asyncio.shield(ft)
      ct = asyncio.ensure_future(c(shielded_ft))
    
      try:
        r = await shielded_ft
      except asyncio.CancelledError:
        print('Shield cancelled')
        r = await ft
    

提交回复
热议问题