为什么我在 Python asyncio 中收到 "Task was destroyed but it is pending" 错误?
Why am I getting a "Task was destroyed but it is pending" error in Python asyncio?
我用asyncio
又漂亮aiohttp
。主要思想是我向服务器发出请求(它是 returns 链接),然后我想从 parallel 中的所有链接下载文件(类似于 example).
代码:
import aiohttp
import asyncio
@asyncio.coroutine
def downloader(file):
print('Download', file['title'])
yield from asyncio.sleep(1.0) # some actions to download
print('OK', file['title'])
def run():
r = yield from aiohttp.request('get', 'my_url.com', True))
raw = yield from r.json()
tasks = []
for file in raw['files']:
tasks.append(asyncio.async(downloader(file)))
asyncio.wait(tasks)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(run())
但是,当我尝试 运行 它时,我有很多 "Download ..." 输出和
Task was destroyed but it is pending!
'OK + filename'.
什么都没有
我该如何解决?
您忘记 yield from
呼叫 asyncio.wait
。您的缩进也可能有误;在遍历整个 raw['files']
列表后,您只想 运行 它。这是修复了两个错误的完整示例:
import aiohttp
import asyncio
@asyncio.coroutine
def downloader(file):
print('Download', file['title'])
yield from asyncio.sleep(1.0) # some actions to download
print('OK', file['title'])
@asyncio.coroutine
def run():
r = yield from aiohttp.request('get', 'my_url.com', True))
raw = yield from r.json()
tasks = []
for file in raw['files']:
tasks.append(asyncio.async(downloader(file)))
yield from asyncio.wait(tasks)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(run())
如果不调用 yield from
,run
会在您遍历整个文件列表后立即退出,这意味着您的脚本会退出,导致一大堆未完成的 downloader
待销毁的任务,并显示您看到的警告。
我用asyncio
又漂亮aiohttp
。主要思想是我向服务器发出请求(它是 returns 链接),然后我想从 parallel 中的所有链接下载文件(类似于 example).
代码:
import aiohttp
import asyncio
@asyncio.coroutine
def downloader(file):
print('Download', file['title'])
yield from asyncio.sleep(1.0) # some actions to download
print('OK', file['title'])
def run():
r = yield from aiohttp.request('get', 'my_url.com', True))
raw = yield from r.json()
tasks = []
for file in raw['files']:
tasks.append(asyncio.async(downloader(file)))
asyncio.wait(tasks)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(run())
但是,当我尝试 运行 它时,我有很多 "Download ..." 输出和
Task was destroyed but it is pending!
'OK + filename'.
什么都没有我该如何解决?
您忘记 yield from
呼叫 asyncio.wait
。您的缩进也可能有误;在遍历整个 raw['files']
列表后,您只想 运行 它。这是修复了两个错误的完整示例:
import aiohttp
import asyncio
@asyncio.coroutine
def downloader(file):
print('Download', file['title'])
yield from asyncio.sleep(1.0) # some actions to download
print('OK', file['title'])
@asyncio.coroutine
def run():
r = yield from aiohttp.request('get', 'my_url.com', True))
raw = yield from r.json()
tasks = []
for file in raw['files']:
tasks.append(asyncio.async(downloader(file)))
yield from asyncio.wait(tasks)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(run())
如果不调用 yield from
,run
会在您遍历整个文件列表后立即退出,这意味着您的脚本会退出,导致一大堆未完成的 downloader
待销毁的任务,并显示您看到的警告。