我的函数run_tasks(all_tasks, window_size)
,它接受asyncio
个任务的生成器,并在以下情况下返回其值:
window_size
all_tasks
)
all_tasks[i]
结果为results[i]
)我目前的实施:
import asyncio
from itertools import islice
# run all tasks and return their results in the same order
# window is the max number of tasks that will run in parallel
def run_tasks(all_tasks, window_size=4):
loop = asyncio.get_event_loop()
while True:
window_tasks = list(islice(all_tasks, window_size))
if not window_tasks:
break
futures = asyncio.wait(window_tasks, loop=loop)
finished, unfinished = loop.run_until_complete(futures)
# sort finished tasks by their launch order.
# removing this line makes returned tasks unordered
finished = sorted(finished, key=lambda f: window_tasks.index(f._coro))
for finished_task in finished:
try:
yield finished_task.result()
except Exception as e:
yield repr(e)
# Example Usage:
# a coroutine that sometime raises exception
async def sleepy(i):
print(f'{i} started')
await asyncio.sleep(10 - i)
print(f'{i} finished')
if i == 5:
raise ValueError('5 is the worst')
return i
# a generator of tasks
all_tasks = (sleepy(i) for i in range(10))
for result in list(run_tasks(all_tasks)):
print(result)
我的实现问题是,我无法在不访问f._coro
对象的内部属性asyncio.Task
的情况下找到对任务进行排序的方法。
# removing this line makes returned tasks unordered
finished = sorted(finished, key=lambda f: window_tasks.index(f._coro))
我可以使用asyncio.gather(*tasks)
,但这不会处理错误。
我愿意接受有关如何为run_tasks()
实施此三个属性而无法访问f._coro
的建议。
答案 0 :(得分:2)
void main(){
gl_PointSize = 100.;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.);
}
,则 asyncio.gather
can会返回错误。为了区分真实异常和异常对象返回作为协程的结果,您可以使用return_exceptions
将window_tasks
包裹在任务中:
ensure_future