RuntimeError: Il n'y a pas de courant de boucle d'événement de fil en asynchrone + apscheduler
J'ai une fonction async et besoin pour exécuter avec apscheduller toutes les N minutes.
Il y a un code python ci-dessous
URL_LIST = ['<url1>',
'<url2>',
'<url2>',
]
def demo_async(urls):
"""Fetch list of web pages asynchronously."""
loop = asyncio.get_event_loop() # event loop
future = asyncio.ensure_future(fetch_all(urls)) # tasks to do
loop.run_until_complete(future) # loop until done
async def fetch_all(urls):
tasks = [] # dictionary of start times for each url
async with ClientSession() as session:
for url in urls:
task = asyncio.ensure_future(fetch(url, session))
tasks.append(task) # create list of tasks
_ = await asyncio.gather(*tasks) # gather task responses
async def fetch(url, session):
"""Fetch a url, using specified ClientSession."""
async with session.get(url) as response:
resp = await response.read()
print(resp)
if __name__ == '__main__':
scheduler = AsyncIOScheduler()
scheduler.add_job(demo_async, args=[URL_LIST], trigger='interval', seconds=15)
scheduler.start()
print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C'))
# Execution will block here until Ctrl+C (Ctrl+Break on Windows) is pressed.
try:
asyncio.get_event_loop().run_forever()
except (KeyboardInterrupt, SystemExit):
pass
Mais quand j'ai essayé j'ai l'erreur suivante info
Job "demo_async (trigger: interval[0:00:15], next run at: 2017-10-12 18:21:12 +04)" raised an exception.....
..........\lib\asyncio\events.py", line 584, in get_event_loop
% threading.current_thread().name)
RuntimeError: There is no current event loop in thread '<concurrent.futures.thread.ThreadPoolExecutor object at 0x0356B150>_0'.
Pourriez-vous svp m'aider?
Python 3.6, APScheduler 3.3.1,
Vous devez vous connecter pour publier un commentaire.
Juste passer
fetch_all
àscheduler.add_job()
directement. Le asyncio planificateur prend en charge coroutine fonctions des objectifs d'emplois.Si la cible appelable est pas une coroutine fonction, elle sera exécutée dans un thread de travail (pour des raisons historiques), d'où l'exception.
Dans votre
def demo_async(urls)
, essayez de le remplacer:avec:
La chose la plus importante qui n'a pas été mentionné, c'est pourquoi le message d'erreur se produit. Pour moi personnellement, le fait de savoir pourquoi l'erreur se produit est aussi important que la résolution du problème réel.
Prenons un coup d'oeil à la mise en œuvre de la
get_event_loop
deBaseDefaultEventLoopPolicy
:Vous pouvez voir que le
self.set_event_loop(self.new_event_loop())
est exécuté seulement si toutes les conditions suivantes sont remplies:self._local._loop is None
-_local._loop
n'est pas définienot self._local._set_called
-set_event_loop
n'a pas été appelée encoreisinstance(threading.current_thread(), threading._MainThread)
- thread courant est le principal (ce n'est pas Vrai dans votre cas)Par conséquent, l'exception est soulevée, parce que pas de boucle est définie dans le thread actuel:
isinstance...
condition est-elle importante? Pourquoi avons-nous seulement de créer de boucle d'événement dans le _MainThread?Utilisation
asyncio.run()
au lieu d'utiliser directement la boucle d'événements.Il crée une nouvelle boucle et se ferme lorsque vous avez terminé.
C'est la façon dont le " run " ressemble:
Depuis que cette question continue à apparaître sur la première page, je vais écrire mon problème et ma réponse ici.
J'ai eu un
RuntimeError: There is no current event loop in thread 'Thread-X'.
lors de l'utilisation de en flacon de socketio et Sombre.Edit: bien, j'ai refait mon dossier et fait une classe.
J'ai initialisé la boucle dans le constructeur, et maintenant tout fonctionne bien:
Utilisation:
Réponse originale à cette question:
La solution était stupide. Je n'avais pas fait attention à ce que j'ai fait, mais j'ai déménagé quelques
import
hors d'une fonction, comme ceci:Alors j'ai pensé que je devais changer quelque chose dans mon code, et j'ai créé une nouvelle boucle d'événement à l'aide de ce morceau de code juste avant la ligne avec
get_event_loop()
:En ce moment, j'ai été assez heureux, car j'avais une boucle en cours d'exécution.
Mais ne répond pas. Et mon code invoqué un délai d'attente pour le retour de certaines valeurs, de sorte qu'il était assez mauvais pour mon application.
Il m'a fallu près de deux heures pour comprendre que le problème est le
import
, et voici mon (travail) code: