在python中异步io操作问题使用了asyncio模块

用异步IO操作出现这样的错误是怎么回事


import asyncio
from threading import Thread, current_thread


async def recv():
    print('进⼊IO')
    await asyncio.sleep(3)
    print('结束IO')
    return 'hello'


async def f1():
    print('f1 start', current_thread())
    data = await recv()
    print('结果', data)
    print('f1 end', current_thread())


async def f2():
    print('f2 start', current_thread())
    data = await recv()
    print('结果', data)
    print('f2 end', current_thread())


tasks = [f1(), f2()]
asyncio.run(asyncio.wait(tasks))

错误代码

Traceback (most recent call last):
  File "E:\wgt python\网络编程\3.7异步IO.py", line 27, in <module>
    asyncio.run(asyncio.wait(tasks))
  File "C:\Users\r9000p\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "C:\Users\r9000p\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\r9000p\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 653, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "C:\Users\r9000p\AppData\Local\Programs\Python\Python311\Lib\asyncio\tasks.py", line 415, in wait
    raise TypeError("Passing coroutines is forbidden, use tasks explicitly.")
TypeError: Passing coroutines is forbidden, use tasks explicitly.
sys:1: RuntimeWarning: coroutine 'f2' was never awaited
sys:1: RuntimeWarning: coroutine 'f1' was never awaited

Process finished with exit code 1



 
import asyncio
from threading import Thread, current_thread
 
 
async def recv():
    print('进⼊IO')
    await asyncio.sleep(3)
    print('结束IO')
    return 'hello'
 
 
async def f1():
    print('f1 start', current_thread())
    data = await recv()
    print('结果', data)
    print('f1 end', current_thread())
 
 
async def f2():
    print('f2 start', current_thread())
    data = await recv()
    print('结果', data)
    print('f2 end', current_thread())
 
async def main():
    tasks = [f1(), f2()]
    results = await asyncio.gather(*tasks, return_exceptions=True)


if __name__ == '__main__':
    
    asyncio.run(main())

经过代码的验证,没问题,可以正常运行(本人用的python3.9).
分析思路:猜测应该是版本差异导致的问题. 升级一下开发环境

【以下回答由 GPT 生成】

问题原因是在使用asyncio.wait函数时传入了coroutine对象,而不是task对象。asyncio.wait函数要求传入task对象而不是coroutine对象。

解决方法是将coroutine对象包装为task对象,可以使用asyncio.create_task函数来创建task对象。在创建task对象时,不需要直接使用await关键字,而是将coroutine对象传入create_task函数中即可。

以下是修改后的代码:

import asyncio
from threading import Thread, current_thread


async def recv():
    print('进入IO')
    await asyncio.sleep(3)
    print('结束IO')
    return 'hello'


async def f1():
    print('f1 start', current_thread())
    data = await recv()
    print('结果', data)
    print('f1 end', current_thread())


async def f2():
    print('f2 start', current_thread())
    data = await recv()
    print('结果', data)
    print('f2 end', current_thread())


tasks = [asyncio.create_task(f1()), asyncio.create_task(f2())]
asyncio.run(asyncio.wait(tasks))

将coroutine对象f1()f2()传入asyncio.create_task函数中,创建对应的task对象。 然后将创建的task对象作为参数传递给asyncio.wait函数即可。

这样修改后的代码就能够正确运行了。



【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^