Was ist der Unterschied zwischen Ausrufezeichen ( !
) und Fragezeichen ( ?
) beim Senden von Nachrichten an Schauspieler?
myActor ! Hello(value1)
myActor ? Hello(value1)
Antworten:
Schamlos kopiertes [fantastisches] offizielles Dokument (weitere Informationen finden Sie im Abschnitt Nachrichten senden ):
Nachrichten werden über eine der folgenden Methoden an einen Akteur gesendet.
!
bedeutet "Feuer und Vergessen", z. B. asynchron eine Nachricht senden und sofort zurückkehren. Auch bekannt alstell
.
?
sendet eine Nachricht asynchron und gibtFuture
eine mögliche Antwort zurück. Auch bekannt alsask
.
Aus Sicht des Empfängers werden die Nachrichten auf dieselbe Weise angezeigt tell
und ask
gesendet. Allerdings , wenn ein Empfang tell
des Wertes sender
wird der Schauspieler sein die Referenz, die die Nachricht gesendet, während für eine ask
, die sender
derart eingerichtet ist, dass jede Antwort auf die geht Future
in den Schauspieler geschaffen , die den geforderten tat.
Es hat den Vorteil ask
, dass leicht zu erkennen ist, dass die Antwort, die Sie erhalten, definitiv auf die von Ihnen angeforderte Nachricht zurückzuführen ist, während Sie bei Tell möglicherweise eindeutige IDs verwenden müssen, um ein ähnliches Ergebnis zu erzielen. Jedoch mit ask
benötigen Sie einen einstellen , timeout
nach der das Future
fehl , wenn keine Antwort empfangen wird.
Im folgenden Code wird der gleiche Effekt mit einem tell
und und erzielt ask
.
import akka.actor.{Props, Actor}
import scala.concurrent.duration._
import akka.pattern.ask
class TellActor extends Actor {
val recipient = context.actorOf(Props[ReceiveActor])
def receive = {
case "Start" =>
recipient ! "Hello" // equivalent to recipient.tell("hello", self)
case reply => println(reply)
}
}
class AskActor extends Actor {
val recipient = context.actorOf(Props[ReceiveActor])
def receive = {
case "Start" =>
implicit val timeout = 3 seconds
val replyF = recipient ? "Hello" // equivalent to recipient.ask("Hello")
replyF.onSuccess{
case reply => println(reply)
}
}
}
class ReceiveActor extends Actor {
def receive = {
case "Hello" => sender ! "And Hello to you!"
}
}