Избегайте трассировки после CTRL + C в асинхронном режиме - PullRequest
0 голосов
/ 08 апреля 2020

Я сейчас изучаю async / await в python.

Я хотел бы запустить Pyrogram, а затем запустить функцию cronjob. Я создал этот код:

import asyncio
from pyrogram import Client, Filters, MessageHandler
import time

app = Client("pihome")

async def cronjob():
    print("Cronjob started")
    while True:
        #print(f"time is {time.strftime('%X')}")
        print(int(time.time()))
        if int(time.strftime('%S')) == 10:
            print("SECONDO 10") # Change this with checks in future

        await asyncio.sleep(1)

async def main():
    print(f"Starting {app.session_name}...\n")
    # Pyrogram
    await app.start()
    print("Pyrogram started")

    # Cronjob
    loop = asyncio.new_event_loop()
    loop.run_until_complete(loop.create_task(await cronjob()))
    print("\nDone")

    await Client.idle()
    await app.stop()

    print(f"\nStopping {app.session_name}...")

if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())

Но когда я хочу остановить его с помощью Ctrl + C, он дает мне следующую трассировку:

^CTraceback (most recent call last):
  File "pihome.py", line 39, in <module>
    asyncio.get_event_loop().run_until_complete(main())
  File "/usr/local/lib/python3.8/asyncio/base_events.py", line 603, in run_until_complete
    self.run_forever()
  File "/usr/local/lib/python3.8/asyncio/base_events.py", line 570, in run_forever
    self._run_once()
  File "/usr/local/lib/python3.8/asyncio/base_events.py", line 1823, in _run_once
    event_list = self._selector.select(timeout)
  File "/usr/local/lib/python3.8/selectors.py", line 468, in select
    fd_event_list = self._selector.poll(timeout, max_ev)
KeyboardInterrupt

Как я могу решить это? Кроме того, попробуйте / кроме блоков, кажется, не работает

1 Ответ

1 голос
/ 08 апреля 2020
  1. Для запуска приложения лучше использовать asyncio.run (main ()) . На мой взгляд, это более понятно.

  2. Заменить l oop = asyncio. new_event_l oop () на l oop = asyncio. get_event_l oop () . Потому что, используя asyncio.new_event_l oop () после asyncio.get_event_l oop (). Run_until_complete (main ()), вы создаете второе событие l oop в главном потоке, которое запрещено. Допускается только одно событие l oop на поток!

  3. Удалить await из этой строки:

    l oop .run_until_complete (l oop .create_task (await cronjob ()))

Поскольку create_task необходимо Coroutine в качестве первого аргумента, но вы передаете его None

...