2016-05-31 6 views
2

akka.netに問題があります。私はすでに特定の名前で作成した俳優にアクセスする必要があります。私はIActorContextからアクターを取得することができますが、私はActorSystemからアクターにアクセスしようとしています。Akka.net ActorSelectionのデッドロック問題

ActorSelectionを使用してアクタを取得しようとするGetOrCreateActorというメソッドを作成しました。存在しない場合、キャッチはその名前の新しいアクタを作成します。それが存在する場合、私は参照を返すようにします。ただし、 '。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); 
     } 
    } 

編集 私は以下の呼び出しコードの簡易版を含めるようにしようとしました。

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メソッドを呼び出して別のクラスに注入される(経由:

俳優・システムはAutoFacを使用してIOCコンテナに作成された(ExampleActorは、私がアクセスしようとしていますReceiveActorです) Executeメソッド):上記のコマンドは、RESTfulなエンドポイントから呼び出されます

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); 
    } 
} 

public ExampleGetModule(IExampleCommand exampleCommand) 
{ 
    Get["/api/createExample"] = parameters => 
    { 
     exampleCommand.Execute(); 
    }; 
} 
+0

詳細をお知らせください。たとえば、デッドロックが発生したときにメソッドがどのように呼び出されますか? 'GetOrCreateActor'を呼び出す' async'メソッドですか? – easuter

+0

私は詳細を提供するために質問を編集しました。 – Kelly

答えて

0

それは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>種類があります悪名高い競争条件の原因containerBuilder.Buildの出力がcontainerBuilder.Registerの入力に依存する場合は、この登録方法の中でlazyContainer.Valueを呼び出すべきではありません。

最後に、アプリケーションが実際にResolveOneメソッドを呼び出していることを確認するためにステップスルーデバッグを使用します。タイムアウト例外が戻ってこない場合は、アクターシステムの作成時にアプリケーションがデッドロックしていることを意味します(DIがどのように構成されているかにより)。

関連する問題