简单写一个已经运行event_loop添加新任务

A simple way to write an already running event_loop to add a new task

我想做的是稍后再添加任务到一个持久的(最好是空的)event_loop。

我也想在任意时间结束event_loop

此代码旨在 运行 服务器上。

我自己试过了

(1)创建任务时使用call_soon、create_task和ensure_future

(2)使用run_forever来运行任务

我写了下面的代码,我认为我可以用我自己的方式实现。

但是,此代码将每 10 秒执行不需要执行的操作。

而且我不能随意结束event_loop。

综上所述,请告诉我以下两点

(1)如何使第一个 event_loop 简单而不阻塞稍后将添加的任务

(2)如何在任何给定时间停止event_loop

import threading
import asyncio


async def long_task():
    i = 0
    while True:
        print(i)
        await asyncio.sleep(10)
        i = i+1


async def create_long_task(loop):
    t = loop.create_task(long_task())
    await t


def run_long_task():
    loop.run_until_complete(create_long_task(loop))


def new_task():
    print('----------------------------')


loop = asyncio.get_event_loop()
thread1 = threading.Thread(target=run_long_task)
thread1.start()

thread2 = threading.Thread(target=new_task)
thread2.start()

后记

看了评论重写了

但是我用这段代码也无法实现。

如果我在“long_task()”、“new_task()”中将“await asyncio.sleep(3)”更改为“time.sleep(3)”将被阻止。

将其重写为“await time.sleep(3)”会出现以下错误。

[TypeError: object NoneType 不能在 'await' 表达式中使用]

如何重写?

我想做的是先创建一个空的 event_loop,因为我不想添加更多的 event_loop,然后将必要的任务添加到 event_loop.

我想启动服务器并有一个空循环运行ning,然后根据需要添加任务。

import threading
import asyncio


async def long_task():
   i = 0
   while True:
       print(i)
       await asyncio.sleep(10)
       i = i+1


async def create_long_task(loop):
   t = loop.create_task(long_task())
   await t


def run_long_task():
   loop.run_until_complete(create_long_task(loop))


async def new_task():
   i = 0
   while True:
       print("---{}--".format(i))
       await asyncio.sleep(10)
       i = i+1


def add_task(loop):
   t = loop.create_task(new_task())
   t


def add_thread(loop):
   thread = threading.Thread(
       target=add_task, args=(loop,))
   thread.start()
   thread.join
   print("new thread end")


loop = asyncio.get_event_loop()
thread1 = threading.Thread(target=run_long_task)
thread1.start()

add_thread(loop)

您可以使用 asyncio.run_coroutine_threadsafe 将任务发送到 运行 循环。您可以在单独的线程中通过 运行 run_forever 开始循环,然后将任务提交到该循环,就像您想要的那样:

import threading, asyncio, time

def run_loop(loop):
    asyncio.set_event_loop(loop)
    loop.run_forever()

async def new_task():
    print('a')
    await asyncio.sleep(1)
    print('b')

def main():
    loop = asyncio.new_event_loop()
    threading.Thread(target=run_loop, args=(loop,)).start()

    asyncio.run_coroutine_threadsafe(new_task(), loop)
    # sleep while the task runs in the background
    time.sleep(2)
    print('exiting')
    loop.call_soon_threadsafe(loop.stop)

if __name__ == '__main__':
    main()