Manchmal muss ein unkritischer asynchroner Vorgang ausgeführt werden, aber ich möchte nicht warten, bis er abgeschlossen ist. In der Coroutine-Implementierung von Tornado können Sie eine asynchrone Funktion "auslösen und vergessen", indem Sie einfach das yield
Schlüsselwort weglassen .
Ich habe versucht , zu , um herauszufinden , wie „Feuer & Forget“ mit der neuen async
/ await
Syntax in Python 3.5 freigegeben. ZB ein vereinfachtes Code-Snippet:
async def async_foo():
print("Do some stuff asynchronously here...")
def bar():
async_foo() # fire and forget "async_foo()"
bar()
Was jedoch passiert, ist, dass es bar()
niemals ausgeführt wird und stattdessen eine Laufzeitwarnung angezeigt wird:
RuntimeWarning: coroutine 'async_foo' was never awaited
async_foo() # fire and forget "async_foo()"
python
python-3.5
python-asyncio
Mike N.
quelle
quelle
Antworten:
Aktualisieren:
Ersetzen Sie
asyncio.ensure_future
durchasyncio.create_task
überall, wenn Sie Python verwenden> = 3.7 Es ist eine neuere, schönere Möglichkeit , Aufgaben zu erzeugen .asyncio.Task zu "feuern und vergessen"
Laut Python-Dokumenten
asyncio.Task
ist es möglich, eine Coroutine zu starten, um "im Hintergrund" auszuführen . Die von derasyncio.ensure_future
Funktion erstellte Aufgabe blockiert die Ausführung nicht (daher kehrt die Funktion sofort zurück!). Dies scheint eine Möglichkeit zu sein, wie gewünscht zu „feuern und zu vergessen“.Ausgabe:
Was ist, wenn Aufgaben nach Abschluss der Ereignisschleife ausgeführt werden?
Beachten Sie, dass Asyncio erwartet, dass die Aufgabe zum Zeitpunkt des Abschlusses der Ereignisschleife abgeschlossen ist. Wenn Sie also wechseln
main()
zu:Sie erhalten diese Warnung, nachdem das Programm beendet wurde:
Um zu verhindern, dass Sie nach Abschluss der Ereignisschleife einfach auf alle ausstehenden Aufgaben warten können :
Töte Aufgaben, anstatt sie abzuwarten
Manchmal möchten Sie nicht darauf warten, dass Aufgaben erledigt werden (einige Aufgaben können beispielsweise so erstellt werden, dass sie für immer ausgeführt werden). In diesem Fall können Sie sie einfach abbrechen (), anstatt sie abzuwarten:
Ausgabe:
quelle
stop()
Methode stirbt .Vielen Dank, Sergey, für die kurze Antwort. Hier ist die dekorierte Version davon.
Produziert
Hinweis: Überprüfen Sie meine andere Antwort, die dasselbe tut, mit einfachen Threads.
quelle
Dies ist keine vollständig asynchrone Ausführung, aber möglicherweise ist run_in_executor () für Sie geeignet.
quelle
executor
Wille standardmäßig anruftconcurrent.futures.ThreadPoolExecutor.submit()
. Ich erwähne, weil das Erstellen von Threads nicht kostenlos ist. 1000-mal pro Sekunde Feuer und Vergessen wird wahrscheinlich das Thread-Management stark belastenWenn Sie aus irgendeinem Grund nicht verwenden können, finden Sie
asyncio
hier die Implementierung mit einfachen Threads. Überprüfen Sie meine anderen Antworten und auch die Antwort von Sergey.quelle