[英]Akka.net deadlocking issue with ActorSelection
akka.net出現問題。 我需要訪問一個已經使用特定名稱創建的演員。 我可以從IActorContext檢索actor,但正在努力從ActorSystem訪問它。
我創建了一個名為GetOrCreateActor的方法,該方法嘗試使用ActorSelection獲取演員。 如果不存在,則捕獲將使用該名稱創建一個新演員。 如果確實存在,我希望它返回引用。 但是,它永遠不會從“ .Result”返回。 假設這可能是某種僵局的問題。
public static IActorRef GetOrCreateActor<T>(this ActorSystem actorSystem, string actorPath, string name = null) where T : ActorBase
{
try
{
return actorSystem.ActorSelection(actorPath).ResolveOne(TimeSpan.FromSeconds(1)).Result;
}
catch
{
return actorSystem.ActorOf(actorSystem.DI().Props<T>(), name);
}
}
編輯我試圖在下面添加簡化版本的調用代碼。
使用AutoFac在IOC容器中創建actor系統(ExampleActor是我嘗試訪問的ReceiveActor):
containerBuilder.RegisterAssemblyTypes(typeof(ExampleActor).Assembly).Where(x => x.Name.EndsWith("Actor"));
var lazyContainer = new Lazy<IContainer>(() => containerBuilder.Build());
containerBuilder.Register(c =>
{
var system = ActorSystem.Create("ExampleActorSystem");
new AutoFacDependencyResolver(lazyContainer.Value, system);
return system;
}).As<ActorSystem>().SingleInstance();
return lazyContainer.Value;
然后將ActorSystem注入到另一個類中,在這里我調用GetOrCreateActor方法(通過Execute方法):
public class ExampleCommand : IExampleCommand
{
private readonly ActorSystem _actorSystem;
public ExampleCommand(ActorSystem actorSystem)
{
_actorSystem = actorSystem;
}
public void Execute()
{
SendMessage();
}
private void SendMessage()
{
string message = new Message();
_actorSystem.GetOrCreateActor<ExampleActor>("akka://ExampleActorSystem/user/ExampleActor", "ExampleActor").Tell(message);
}
}
上面的命令將從RESTful端點調用
public ExampleGetModule(IExampleCommand exampleCommand)
{
Get["/api/createExample"] = parameters =>
{
exampleCommand.Execute();
};
}
與Akka.NET相比,死鎖問題更像是與您使用容器的方式有關:
var lazyContainer = new Lazy<IContainer>(() => containerBuilder.Build());
containerBuilder.Register(c =>
{
var system = ActorSystem.Create("ExampleActorSystem");
new AutoFacDependencyResolver(lazyContainer.Value, system);
return system;
}).As<ActorSystem>().SingleInstance();
就這里可能出問題的方面而言,自指Lazy<T>
類型是臭名昭著的競爭條件。 你不應該調用lazyContainer.Value
這種注冊方法里面,如果輸出containerBuilder.Build
取決於輸入containerBuilder.Register
。
最后一件事是使用逐步調試來確保您的應用程序實際上在這里調用ResolveOne
方法-如果您沒有收到超時異常,則意味着您的應用程序在生成actor系統時陷入僵局(因為DI已配置)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.