8.13. Schleifensteuerung#

Die meisten asyncio-Skripte greifen nie direkt auf die Ereignisschleife zu – asyncio.run() genügt. Diese Seite behandelt die Loop-Schnittstelle für die Fälle, in denen das nicht ausreicht: das Installieren eines Ausnahmehandlers, das Ausführen der Schleife mit einem anderen Lebenszyklus als run oder das Festhalten des Schleifenobjekts zu Instrumentierungszwecken.

8.13.1. Die Schleife abrufen#

  • asyncio.get_event_loop() – gibt das Loop-Objekt zurück. Kann sicher von innerhalb oder außerhalb einer Koroutine aufgerufen werden.

  • asyncio.new_event_loop() – setzt in MicroPython den Zustand der bestehenden Schleife zurück, anstatt eine neue zu erzeugen. Der Hinweis sei wiederholt: Es gibt genau eine Ereignisschleife pro Programm.

Es gibt keine API zum Ausführen der Schleife außer den Methoden von Loop und asyncio.run().

8.13.2. Die Schleife direkt ausführen#

asyncio.run() ist der richtige Einstiegspunkt für nahezu jede Anwendung. Für die Fälle, in denen das nicht zutrifft, existieren zwei Loop-Methoden.

  • run_until_complete() – führt bei einem gegebenen Awaitable die Schleife aus, bis dieses Awaitable abgeschlossen ist, und gibt dann sein Ergebnis zurück. Entspricht einem einzelnen asyncio.run()-Aufruf, jedoch ohne den Abbau der Schleife.

  • run_forever() – führt die Schleife aus, bis stop() aus einem Task heraus aufgerufen wird. Kein Top-Level-Awaitable; von der Anwendung wird erwartet, dass sie vor dem Aufruf von run_forever über asyncio.create_task() einplant, was immer sie benötigt.

Die zugehörigen Methoden sind stop() (fordert das Anhalten der Schleife nach Abschluss des aktuellen Tasks an) und close() (gibt die Ressourcen der Schleife frei).

8.13.3. Task-Erstellung auf Schleifenseite#

  • create_task() – dieselbe Operation wie asyncio.create_task(). Die freie Funktion existiert, damit Anwendungscode für den häufigen Fall keine Schleifenreferenz benötigt; die Methode existiert für Instrumentierung, die bereits über eine solche verfügt.

8.13.4. Ausnahmehandler#

Die Schleife ruft einen Handler auf, wenn ein Task eine Ausnahme auslöst, die nichts in der Koroutinen-Aufrufkette abgefangen hat – ein typischer Fall ist ein Task, den die Anwendung mit asyncio.create_task() erzeugt und nie awaitet hat. Der Standard-Handler gibt einen Traceback über sys.stderr aus; die Seite Ausnahmen hat gezeigt, wie man ihn durch einen eigenen ersetzt.

  • set_exception_handler() – installiert einen eigenen Handler. Der Handler ist ein Callable handler(loop, context), wobei context ein Dict ist, das mindestens 'message' und üblicherweise 'exception' und 'future' enthält.

  • get_exception_handler() – gibt den aktuell installierten Handler zurück, oder None, wenn der Standard verwendet wird.

  • default_exception_handler() – der eingebaute Handler. Nützlich innerhalb eines eigenen Handlers, der zusätzlich das Standardverhalten ausführen möchte (zum Beispiel ins Flash protokollieren und einen Traceback ausgeben).

  • call_exception_handler() – führt den aktuell installierten Handler mit einem von Hand erstellten Kontext-Dict aus. Wird meist von der Schleife selbst verwendet; eine Anwendung benötigt es selten.