实验 11:调试和易错点
最后看两个常见错误:创建 coroutine 但没等待;在 async def 里调用阻塞函数。
运行:
bash
python3 examples/asyncio_demos/11_debug_antipatterns.py忘记 await
示例里故意写了:
python
forgotten_await()这只创建 coroutine object,不会执行函数体。debug 模式下,你会看到类似“coroutine was never awaited”的警告。
改法:
python
await forgotten_await()如果你想让它后台运行,也不要裸写,至少保存 Task:
python
task = asyncio.create_task(forgotten_await())然后你要决定后面在哪里等待它、谁处理它的异常。
阻塞事件循环
示例里还故意写了:
python
time.sleep(0.2)time.sleep() 会把当前线程睡住。事件循环也在这个线程里,所以别的 Task 没机会运行。
改法:
python
await asyncio.sleep(0.2)如果你绕不开同步阻塞函数,可以临时放到线程里:
python
result = await asyncio.to_thread(blocking_function, arg)这适合包一小段旧代码,不适合把大量 CPU 计算都塞进去。
打开 debug
示例入口是:
python
asyncio.run(main(), debug=True)还设置了慢 callback 阈值:
python
loop.slow_callback_duration = 0.05所以 time.sleep(0.2) 会被记录出来。线上不一定要一直开 debug,但开发和排查问题时很有用。
小练习
- 把
forgotten_await()改成await forgotten_await(),确认警告消失。 - 把
time.sleep(0.2)改成await asyncio.sleep(0.2),确认慢 callback 提示消失。 - 把一个普通同步函数放进
asyncio.to_thread(),观察事件循环是否还能处理别的 Task。