我正在玩asyncio
,但无法实现我想要达到的目标。这是我的代码。
import random
import asyncio
async def my_long_operation(s: str):
print("Starting operation on", s)
await asyncio.sleep(3)
print("End", s)
def random_string(length: int = 10):
alphabet = \
[chr(x) for x in range(ord('a'), ord('z') + 1)]
result = ""
for i in range(length):
result += random.choice(alphabet)
return result
def get_strings(n = 10):
for i in range(n):
s = random_string()
yield s
async def several(loop):
tasks =list()
for s in get_strings():
task = asyncio.create_task(my_long_operation(s))
asyncio.ensure_future(task, loop = loop)
print("OK")
loop = asyncio.get_event_loop()
loop.run_until_complete(several(loop))
# loop.run_forever()
loop.close()
现在我的问题如下。
我想同时运行所有my_long_operation
,以等待它们完成。问题是,当我运行代码时,出现以下错误:
Task was destroyed but it is pending!
task: <Task pending coro=<my_long_operation() done, defined at test.py:4> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x7f75274f7168>()]>>
这似乎很有意义,因为我的脚本在启动这些操作后即刻结束(无需等待它们完成)。
因此,我们得出了我的实际问题:我应该怎么做?如何在不使用run_forever
的情况下启动这些任务并等待它们完成,然后再终止脚本,而无需使用run_forever
(因为fun getAllDynamicUtterances(): LiveData<ArrayList<DynamicUtterance>>
{
var uttList: ArrayList<DynamicUtterance>? = null
disposable?.add(
repository.getDynamicScreenContent().map { items ->
items.uttSets.map { //items = DynamicUtterance
var utt: DynamicUtterance? = null
utt?.makeUtteranceFromScreenContentResponse(it)
insertDynamicUtterance(utt!!)
repository.updateDynamicUtteranceView(utt,"hi").map{ //it: SelectionStringResponse
utt.assignSelectionStrings(it)
uttList?.add(utt)
//how do i add to all dynamic values?
}
}
}.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()).subscribe ({
allDynamicUtterances?.value = uttList
},{
Log.e("errorHandle",it.toString()) //gets caught here
})
)
return allDynamicUtterances!!
}
从不退出Python ...)
谢谢!
答案 0 :(得分:3)
ensure_future
基本上是“将其放入事件循环中,然后再打扰我”的方法。相反,您要等待所有异步功能的完成。为此,如果对结果不特别感兴趣,请使用asyncio.wait
;如果需要结果,请使用asyncio.gather
:
tasks = map(my_long_operation, get_strings())
await asyncio.wait(list(tasks), loop=loop)
print('OK')