You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python循环二次迭代报错:RuntimeWarning协程'to_thread'未被等待

问题原因分析与解决方案

报错核心原因

  • asyncio.get_event_loop()并非每次调用都会创建新循环:在同一线程内,它会返回已存在的默认事件循环,只有当前线程没有默认循环时才会新建。
  • 第一次循环中你调用loop.close()关闭了默认循环,第二次循环再调用get_event_loop()时,返回的还是那个已关闭的循环。此时用它创建任务(比如asyncio.gather内部会调用loop.create_task)就会触发RuntimeError: Event loop is closed。
  • 至于RuntimeWarning: coroutine 'to_thread' was never awaited,是因为第二次循环里创建的to_thread协程绑定在已关闭的循环上,根本没机会被执行,最终成为未被await的协程。

正确处理方式

方式一:复用同一个事件循环(推荐)

把循环的创建和关闭移到外层,避免重复销毁重建:

import asyncio

def some_func(number):
    print('task number:', number)
    return number

def start():
    loop = asyncio.get_event_loop()
    try:
        for r in range(2):
            print('r:', r)
            tasks = [asyncio.to_thread(some_func, i) for i in range(5)]
            responses = asyncio.gather(*tasks, return_exceptions=True)
            results = loop.run_until_complete(responses)
            print('results:', results)
    finally:
        loop.close()

if __name__ == '__main__':
    start()

方式二:每次循环手动创建新循环(不推荐,开销较大)

如果一定要每次用新循环,需要手动创建并设置为当前线程的默认循环:

import asyncio

def some_func(number):
    print('task number:', number)
    return number

def start():
    for r in range(2):
        print('r:', r)
        # 手动创建新循环并设置为当前线程默认
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        try:
            tasks = [asyncio.to_thread(some_func, i) for i in range(5)]
            responses = asyncio.gather(*tasks, return_exceptions=True)
            results = loop.run_until_complete(responses)
            print('results:', results)
        finally:
            loop.close()

if __name__ == '__main__':
    start()

方式三:用asyncio.run()简化管理(Python 3.7+推荐)

asyncio.run()会自动处理循环的创建、运行和关闭,代码更简洁:

import asyncio

def some_func(number):
    print('task number:', number)
    return number

async def run_batch():
    tasks = [asyncio.to_thread(some_func, i) for i in range(5)]
    return await asyncio.gather(*tasks, return_exceptions=True)

def start():
    for r in range(2):
        print('r:', r)
        results = asyncio.run(run_batch())
        print('results:', results)

if __name__ == '__main__':
    start()

内容的提问来源于stack exchange,提问作者TitanFighter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 16:26:04