等待时如何继续下一个循环?例如:
AjaxControlToolkit.CalendarExtender calender = (AjaxControlToolkit.CalendarExtender)DetailsView3.FindControl("txbkirim");
calender.SelectedDate = DateTime.Now.Date;
如何使async def get_message():
# async get message from queue
return message
async process_message(message):
# make some changes on message
return message
async def deal_with_message(message):
# async update some network resource with given message
async def main():
while True:
message = await get_message()
message = await process_message(message)
await deal_with_message(message)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
循环并发?如果它正在等待while True
,它可以转到下一个循环并运行deal_with_message
?
我想我找到了一个解决方案:
get_message
答案 0 :(得分:3)
您的解决方案可行,但我发现问题。
A
一旦B
启动它就会立即创建新任务并立即发生(async def main():
asyncio.ensure_future(main())
# task finishing
立即创建任务),这与需要时间的此任务的实际完成不同。我想这可能会导致创造大量的任务,从而耗尽你的RAM。
除此之外,它意味着可以同时运行任何大量的任务。它可以消耗你的网络吞吐量或可以同时打开的套接字数量(想象一下你并不想并行下载1 000 000个网址 - 没有任何好处会发生。)
在并发世界中,这个问题通常是can be solved,它通过使用类似Semaphore之类的内容来限制可以同时运行某些合理值的事物的数量。在您的情况下,我认为手动跟踪正在运行的任务量并手动填充它更方便:
main
输出将如下:
ensure_future
这里重要的部分是我们如何在运行任务量减少到少于5之后才能使用下一条消息。
<强> UPD:强>
是的,如果您不需要动态更改最大运行数,信号量似乎更方便。
import asyncio
from random import randint
async def get_message():
message = randint(0, 1_000)
print(f'{message} got')
return message
async def process_message(message):
await asyncio.sleep(randint(1, 5))
print(f'{message} processed')
return message
async def deal_with_message(message):
await asyncio.sleep(randint(1, 5))
print(f'{message} dealt')
async def utilize_message():
message = await get_message()
message = await process_message(message)
await deal_with_message(message)
parallel_max = 5 # don't utilize more than 5 msgs parallely
parallel_now = 0
def populate_tasks():
global parallel_now
for _ in range(parallel_max - parallel_now):
parallel_now += 1
task = asyncio.ensure_future(utilize_message())
task.add_done_callback(on_utilized)
def on_utilized(_):
global parallel_now
parallel_now -= 1
populate_tasks()
if __name__ == '__main__':
loop = asyncio.get_event_loop()
try:
populate_tasks()
loop.run_forever()
finally:
loop.run_until_complete(loop.shutdown_asyncgens())
loop.close()
答案 1 :(得分:1)
最简单的解决方案是asyncio.ensure_future
。
async def main():
tasks = []
while running:
message = await get_message()
message = await process_message(message)
coroutine = deal_with_message(message)
task = asyncio.ensure_future(coroutine) # starts running coroutine
tasks.append(task)
await asyncio.wait(tasks)
如果可以在最后等待所有任务,那么自己跟踪任务是可选的。
async def main():
while running:
message = await get_message()
message = await process_message(message)
coroutine = deal_with_message(message)
asyncio.ensure_future(coroutine)
tasks = asyncio.Task.all_tasks()
await asyncio.wait(tasks)