2016-04-06 6 views
2

Akkaを学ぶための練習として、簡単な問題の簡単な解決策、つまり開始フォルダの下にディレクトリとファイルを効率的に再帰的にリストする方法を書いています。Akka.netのファイルを列挙する

私がDirectory.GetDirectoriesを使用すると、メモリ内のすべてのディレクトリを読み取るブロッキング呼び出しになります。これはうまくいきますが、私はAkkaを使う目的を打ち破ったと思います。

ここでDirectory.EnumerateDirectoriesを使用すると、ディレクトリのために自己にTellを呼び出すことができます。たとえば、ファイルハンドラでTellを呼び出すと、ファイルをログに記録できます。

私の問題は、プロセス全体がいつ完了したか、つまりディレクトリのトラバーサルが完了したことを知る方法がないことです。プログラムはそこに座って、何かをシャットダウンするのを待っています。

私はこの問題を間違った方法で見ていますか?この問題を解決するためにAkkaにはどのようなオプションがありますか?

EDIT:俳優コード

public class DirectoryActor : UntypedActor 
{ 
    private readonly IActorRef fileActor; 

    private readonly string initialPath; 

    public DirectoryActor(IActorRef fileActor, string initialPath) 
    { 
     this.fileActor = fileActor; 
     this.initialPath = initialPath; 
    } 

    protected override void OnReceive(object message) 
    { 
     foreach (string dir in Directory.EnumerateDirectories(message.ToString())) 
     { 
      Self.Tell(dir); 
      foreach (string file in Directory.EnumerateFiles(dir)) 
      { 
       this.fileActor.Tell(file); 
      } 
     } 
    } 
} 
+0

俳優コードを提供できますか? – profesor79

+0

@ profesor79確かに、追加されました。それは目的にかなうはかなり簡単です。 –

答えて

0

を追加し、それは我々がexit文を指定する必要があるように見えます - そして我々が受信され、スキャンのdirsのamoutをを比較することができます - 私たちは、タスクが実行されたときに知っています。

protected override void OnReceive(object message) 
    {    
     dirReceived++; 
     foreach (string dir in Directory.EnumerateDirectories(message.ToString())) 
     { 
      Self.Tell(dir); 
      dirSentCount++; 
      foreach (string file in Directory.EnumerateFiles(dir)) 
      { 
       this.fileActor.Tell(file); 
      } 
     } 

     if (dirReceived == dirSentCount) 
     { 
      Console.WriteLine("Finished"); 
     } 
     else 
     { 
      Console.Write("."); 
     } 
    } 
1

はその中profesor79の答えと同じ前提で、次の作品は、あなたが作業が完了したときに識別するための信号を持っている必要があります。これを行うもう1つの方法は、ReceiveTimeout機能を使用することです。特定の期間メッセージが受信されなかった場合は、タイムアウトメッセージが送信されます。

public class DirectoryActor : UntypedActor 
{ 
    private readonly IActorRef fileActor; 

    private readonly string initialPath; 

    public DirectoryActor(IActorRef fileActor, string initialPath) 
    { 
     this.fileActor = fileActor; 
     this.initialPath = initialPath; 

     this.Context.SetReceiveTimeout(Timespan.FromSeconds(2)); 
    } 

    protected override void OnReceive(object message) 
    { 
     if (message is ReceiveTimeout) return; //No more directories left to enumerate 

     foreach (string dir in Directory.EnumerateDirectories(message.ToString())) 
     { 
      Self.Tell(dir); 
      foreach (string file in Directory.EnumerateFiles(dir)) 
      { 
       this.fileActor.Tell(file); 
      } 
     } 
    } 
} 
関連する問題