Dies ist ähnlich wie Calling coroutines in asyncio.Protocol.data_received, aber ich denke, es garantiert eine neue Frage.Aufruf einer Coroutine aus asyncio.Protocol.data_received
Ich habe einen einfachen Server wie diese feinen Es funktioniert
loop.create_unix_server(lambda: protocol, path=serverSocket)
einrichten, wenn ich dies tun
def data_received(self, data):
data = b'data reply'
self.send(data)
mein Kunde die Antwort bekommt. Aber ich kann es nicht mit irgendeiner Art von asyncio
Aufruf arbeiten. Ich habe alles ausprobiert und keiner von ihnen hat funktioniert.
@asyncio.coroutine
def go(self):
yield from asyncio.sleep(1, result = b'data reply')
def data_received(self, data):
print('Data Received', flush=True)
task = asyncio.get_event_loop().create_task(self.go())
data = yield from asyncio.wait_for(task,10)
self.send(data)
, dass man hing und nichts gedruckt (wenn ich data_received
mit @asyncio.coroutine
verziert ich, dass das nicht von nachgegeben wird) OK, ich bekommen, dass Ausbeute unter Verwendung in data_received
nicht richtig.
Wenn ich eine neue Ereignisschleife versuchen, wie weiter unten, das hängt in run_until_complete
loop = asyncio.new_event_loop()
task = loop.create_task(self.go())
loop.run_until_complete(task)
data = task.result()
self.send(data)
Wenn ich ein Future
verwenden, die in run_until_complete
@asyncio.coroutine
def go(self, future):
yield from asyncio.sleep(1)
future.set_result(b'data reply')
def data_received(self, data):
print('Data Received', flush=True)
loop = asyncio.new_event_loop()
future = asyncio.Future(loop=loop)
asyncio.async(self.go(future))
loop.run_until_complete(future)
data = future.result()
self.send(data)
hängt auch
Die folgenden nahe kommt, aber es gibt sofort zurück und das Ergebnis ist vom Typ asyncio.coroutines.CoroWrapper
, was bedeutet, dass die wait_for
Zeile sofort mit der nicht abgeschlossenen Aufgabe zurückgegeben wurde?
@asyncio.coroutine
def go(self):
return(yield from asyncio.sleep(3, result = b'data reply'))
@asyncio.coroutine
def go2(self):
task = asyncio.get_event_loop().create_task(self.go())
res = yield from asyncio.wait_for(task, 10)
return result
def data_received(self, data):
print('Data Received', flush=True)
data = self.go2()
self.send(data)
Ich bin ein bisschen fest, und würde gerne einige Hinweise darüber, was zu sehen ist.
Hallo, danke für diese Antwort - das funktioniert in meinem Code. Ich habe es nur in meinen nicht-trivialen Code integriert (der einen Calling-Stack usw. hat). Ich hatte über Callbacks nachgedacht, aber ich dachte, dass Rendite/Aufgaben/Futures der neuere Ansatz waren und den Vorteil hatten, sich keine Sorgen zu machen über Ihren Aufruf-Stack oder wie Sie Daten in Ihren Callback bekommen. Weißt du, warum die innere Schleife ihre Arbeit nicht beenden würde? Oder warum der zukünftige Ansatz mit der Hauptschleife nicht funktionieren würde? – Dave
Oh, ich schätze, die innere Schleife wartet auf die geblockte äußere, um ein IO zu machen. – Dave
@Dave 'asyncio' bevorzugt definitiv einen Coroutine-ähnlichen Ansatz für die Verwendung auf höherer Ebene, aber Low-Level-Funktionen wie Protokolle verwenden immer noch die Rückrufart Wenn Sie stattdessen Coroutinen verwenden möchten, empfiehlt [docs] (https://docs.python.org/3/library/asyncio-protocol.html#coroutires-and-protocols) Stream-Objekte anstelle von Protokollen. – dano