繁体   English   中英

如何在不等待的情况下运行 Asyncio 任务?

[英]How to run an Asyncio task without awaiting?

我需要定期调用一个任务,但(a)等待时间几乎超过了这个时期。

在以下代码中,如何运行do_something()任务而无需await结果?

 import asyncio
 import time
 from random import randint

 period = 1  # Second


 def get_epoch_ms():
     return int(time.time() * 1000.0)


 async def do_something(name):
     print("Start  :", name, get_epoch_ms())
     try:
         # Do something which may takes more than 1 secs.
         slp = randint(1, 5)
         print("Sleep  :", name, get_epoch_ms(), slp)
         await asyncio.sleep(slp)
     except Exception as e:
         print("Error  :", e)

     print("Finish :", name, get_epoch_ms())


 async def main():
     i = 0
     while True:
         i += 1
         # Todo : this line should be change
         await do_something('T' + str(i))
         await asyncio.sleep(period)


 asyncio.get_event_loop().run_until_complete(main())

您的问题是使用不满足您的并发目的的run_until_complete(main()) 因此,假设您的协程任务( do_something() )被限制为5 ,您的代码将如下所示:

import time
from random import randint

period = 1  # Second

def get_epoch_ms():
    return int(time.time() * 1000.0)

async def do_something(name):
    print("Start  :", name, get_epoch_ms())
    try:
        # Do something which may takes more than 1 secs.
        slp = randint(1, 5)
        print("Sleep  :", name, get_epoch_ms(), slp)
        await asyncio.sleep(slp)
    except Exception as e:
        print("Error  :", e)

    print("Finish :", name, get_epoch_ms())

loop = asyncio.get_event_loop()
futures = [loop.create_task(do_something('T' + str(i)))
           for i in range(5)]

loop.run_forever()

for f in futures:
    f.cancel()

这是其输出中的并发工作流:

Start  : T0 1558937750705
Sleep  : T0 1558937750705 5
Start  : T1 1558937750705
Sleep  : T1 1558937750705 1
Start  : T2 1558937750705
Sleep  : T2 1558937750705 4
Start  : T3 1558937750705
Sleep  : T3 1558937750705 5
Start  : T4 1558937750705
Sleep  : T4 1558937750705 5
Finish : T1 1558937751707
Finish : T2 1558937754709
Finish : T0 1558937755707
Finish : T3 1558937755708
Finish : T4 1558937755708

但是,如果您的协程任务不受限制,您可以这样做:

...
async def main(loop):
    i = 0
    while True:
        i += 1
        loop.create_task(do_something('T' + str(i)))
        await asyncio.sleep(period)

loop = asyncio.get_event_loop()
loop.run_until_complete(main(loop))

不是await协程,而是调用asyncio.create_task来生成在后台运行的任务对象。 在您的下一次迭代中,您可以检查任务是否完成并相应地等待/取消它。 (否则 asyncio 会抱怨未等待的任务被垃圾收集。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM