2015-11-06 84 views
1

这是例如取消任务:如何取消任务执行,即使它忽略了CancelledError?

import asyncio 


async def some_func(): 
    await asyncio.sleep(2) 
    print('Haha! Task keeps running!') 
    await asyncio.sleep(2) 

async def cancel(task): 
    await asyncio.sleep(1) 
    task.cancel() 

async def main(): 
    func_task = asyncio.ensure_future(some_func()) 
    cancel_task = asyncio.ensure_future(cancel(func_task)) 
    try: 
     await func_task 
    except asyncio.CancelledError: 
     print('Task cancelled as expected') 

if __name__ == "__main__": 
    loop = asyncio.get_event_loop() 
    loop.run_until_complete(main()) 

# Task cancelled as expected 
# [Finished in 1.2s] 

它工作正常,任务被取消。如果抓到里面some_func任务CancelledError不会被取消:

async def some_func(): 
    try: 
     await asyncio.sleep(2) 
    except: 
     pass 
    print('Haha! Task keeps running!') 
    await asyncio.sleep(2) 

# Haha! Task keeps running! 
# [Finished in 3.2s] 

它可以很容易忘记我不应该抑制异常里面异步代码的任何地方(或some_func可以是第三方的代码,例如),但任务应取消。无论如何,我可以做到这一点?或者被忽略CancelledError意味着任务完全不能被取消?

回答

3

您无法取消禁止CancelledError的任务。 这是接近于无法关闭发电机,忽略GeneratorExit

这是故意的行为。任务可能要在取消时做一些额外的工作(例如资源清理),因此捕捉CancelledError可能是个好主意,但压制通常是编程错误的标志。

Python通常允许你拍摄自己的脚,如果你有不妥协的打算这样做。

捕获所有异常甚至禁止通过按键关闭python进程,因为它在内部被翻译为KeyboardInterrupt