从 ActorSystem 或 Context (Akka.NET) 按名称获取演员

Getting an actor by name from ActorSystem or Context (Akka.NET)

是否可以检查ActorSystem中是否存在一个actor?
我只是不想将 IActorRef 引用传递给每个 actors 构造函数,并希望有类似 GetOrCreate 方法的方法来实例化所需的 actor。所以它可能就像我将在整个演员系统中使用的单例演员。

您可以使用 ActorSelection 检查任何演员的存在以要求它识别自己:

var selection = Context.ActorSelection(actorPath);
/// if there's no actor, this operation can timeout
var reply = await selection.Ask<ActorIdentity>(new Identify(null), timeout);

虽然这在任何地方都有效,甚至可以跨越网络边界,但您无法 "just" 从任何地方创建演员。为了创建 actor 需要一个父级 - 一个 actor 系统或另一个 actor。

获取或创建逻辑可以从 actor 内部非常简单地完成:

IActorRef GetOrCreate(string childName)
{
    var child = Context.Child(childName);
    if (Equals(child, ActorRefs.Nobody))
        child = Context.ActorOf(Props.Create(() => new ChildActor()), childName);
    return child;
}

如果您需要使其在分布式环境中工作,Akka.Cluster.Sharding 插件涵盖了此功能。

ActorSelection 有一个名为 "ResolveOne" 的方法,用于检查演员是否存在。根据文档:

Resolves the IActorRef matching this selection. The result is returned as a Task that is completed with the IActorRef if such an actor exists. It is completed with failure ActorNotFoundException if no such actor exists or the identification didn't complete within the supplied timeout

这个方法可以这样使用:

var actorRef = await Context.ActorSelection("Path of Actor !").ResolveOne(TimeSpan.FromSeconds(5));