2016-04-06 11 views
2

Als Übung, um Akka zu lernen, versuche ich eine einfache Lösung für ein scheinbar einfaches Problem zu schreiben - wie effizient Verzeichnisse und Dateien in einem Startordner rekursiv aufzulisten.Auflisten von Dateien in Akka.net

Wenn ich Directory.GetDirectories verwende, wird dies ein blockierender Aufruf sein, der alle Verzeichnisse im Speicher liest. Das funktioniert gut, aber ich denke, es vereitelt den Zweck der Verwendung von Akka.

Jetzt, wenn ich Directory.EnumerateDirectories verwende, kann ich dann Tell an self für Verzeichnisse aufrufen oder Tell auf einem Dateihandler aufrufen, der zum Beispiel die Datei protokolliert.

Mein Problem ist, dass ich keine Möglichkeit habe zu wissen, wann der ganze Prozess fertig ist, das heißt, wenn mein Verzeichnis-Traversal beendet ist. Das Programm sitzt nur da und wartet auf etwas, das es herunterfährt.

Betrachte ich dieses Problem auf die falsche Art? Welche Möglichkeiten habe ich in Akka, um dieses Problem zu lösen?

EDIT: Hinzufügen Schauspieler Code

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

könnten Sie Schauspieler-Code bereitstellen? – profesor79

+0

@ profesor79 Sicher, hinzugefügt. Es ist ziemlich trivial, absichtlich. –

Antwort

0

es sieht aus wie wir eine Exit-Anweisung angeben müssen - dann können wir amout von empfangenen und abgetasteten dirs vergleichen - so wissen wir, wann Aufgabe erledigt ist.

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

Folgende Arbeiten auf der gleichen Prämisse wie die Antwort von profesor79, dass Sie benötigen, um ein Signal haben zu identifizieren, wenn die Arbeit abgeschlossen ist. Eine andere Möglichkeit wäre das Verwenden der ReceiveTimeout-Funktion, die eine Zeitüberschreitungsnachricht auslöst, wenn für eine bestimmte Zeit keine Nachricht empfangen wurde.

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