Wenn Sie der Meinung sind, dass etwas "im Hintergrund" Ihres Asyncio-Programms passieren sollte, ist dies asyncio.Task
möglicherweise eine gute Möglichkeit. In diesem Beitrag erfahren Sie, wie Sie mit Aufgaben arbeiten.
Hier ist eine mögliche Implementierung einer Klasse, die einige Funktionen regelmäßig ausführt:
import asyncio
from contextlib import suppress
class Periodic:
def __init__(self, func, time):
self.func = func
self.time = time
self.is_started = False
self._task = None
async def start(self):
if not self.is_started:
self.is_started = True
self._task = asyncio.ensure_future(self._run())
async def stop(self):
if self.is_started:
self.is_started = False
self._task.cancel()
with suppress(asyncio.CancelledError):
await self._task
async def _run(self):
while True:
await asyncio.sleep(self.time)
self.func()
Testen wir es:
async def main():
p = Periodic(lambda: print('test'), 1)
try:
print('Start')
await p.start()
await asyncio.sleep(3.1)
print('Stop')
await p.stop()
await asyncio.sleep(3.1)
print('Start')
await p.start()
await asyncio.sleep(3.1)
finally:
await p.stop()
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Ausgabe:
Start
test
test
test
Stop
Start
test
test
test
[Finished in 9.5s]
Wie Sie sehen, start
starten wir einfach eine Aufgabe, die einige Funktionen aufruft und einige Zeit in einer Endlosschleife schläft. Auf stop
brechen wir diese Aufgabe einfach ab. Beachten Sie, dass diese Aufgabe zum Zeitpunkt des Programmabschlusses gestoppt werden sollte.
Eine weitere wichtige Sache ist, dass die Ausführung Ihres Rückrufs nicht lange dauern sollte (da sonst Ihre Ereignisschleife einfriert). Wenn Sie vorhaben, etwas Langfristiges aufzurufen func
, müssen Sie es möglicherweise in Executor ausführen .