它Await.receive
是 Scala 并发 API 的一部分,与参与者无关。它的目的是阻塞当前线程,直到提供的未来完成,或者超时限制开始,整个事情以超时异常结束。
ask 操作符?
确实会创建一个临时参与者,其唯一目的是等待变量指向的参与者的回复,aref
并完成您在使用收到的回复调用 ask 操作员时获得的未来。
所以你的代码基本上阻塞了整个线程。如前所述,如果您想释放当前线程并继续做一些其他工作,您可以将回调附加到未来。
implicit val ctx: ExecutionContext = //provide execution context here
implicit val timeout: Timeout = // provide timeout here
aref ? GroupReceive(fromRank)) onSuccess { res =>
//do something with res here, asynchronously
}
// some other code which runs without being blocked...
上面的代码可以用你上面提到的actor DSL重写:
import akka.actor.ActorDSL._
implicit val actorSystem: ActorSystem = // provide an actor system here or any actor ref factory
actor(new Act {
aref ! GroupReceive(fromRank)
context.setReceiveTimeout(timeout) //optional
become {
case ReceiveTimeout => {
//handle the timeout
context.stop(self)
}
case res => {
//do your thing with res, asynchronously
context.stop(self)
}
}
}
//some other code which won't wait for the above operations
后一个版本还创建了一个新的临时actor,它发送GroupReceive
消息然后等待回复,之后它会杀死自己。
底线是,为了接收来自演员的消息,您自己必须是演员。Actor 不能只向ActorRef
.
所以要么你使用 ask 模式在幕后创建一个临时演员并管理这个临时演员的生命周期本身,向你展示一个很好的简单未来可以使用,或者你可以自己创建临时演员,但你必须管理它的生命周期(即记住一旦它完成它的工作就杀死它)
选择最适合您的选项。