2016-04-06 2 views
2

Как упражнение по изучению Akka, я пытаюсь написать простое решение для кажущейся простой проблемы - как эффективно рекурсивно перечислить каталоги и файлы в начальной папке.Перечисление файлов в Akka.net

Если я использую Directory.GetDirectories, это будет блокирующий вызов, который будет читать все каталоги в памяти. Это работает хорошо, но я думаю, что это побеждает цель использования Akka.

Теперь, если я использую Directory.EnumerateDirectories, я могу затем вызвать Tell to self для каталогов или вызвать 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

, похоже, нам нужно указать выездное заявление - тогда мы можем сравнить 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 в этой вам необходимо иметь сигнал, чтобы определить, когда работа завершена. Другой способ сделать это - использовать функцию 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); 
      } 
     } 
    } 
} 
Смежные вопросы