F # MailboxProcessor вопросы - PullRequest
       25

F # MailboxProcessor вопросы

3 голосов
/ 02 июля 2011

Я создал консольную программу, используя код из http://fssnip.net/3K. И я обнаружил, что

  1. Я бы добавил "System.Console.ReadLine () |> игнорировать "в конце ждать окончания потоков".Можно ли сказать, что все MailBoxProcessors завершены, и программа может выйти сама?

  2. Я попытался изменить URL-адрес теста "www.google.com" на недействительный URL-адрес, и я получилследующий вывод.Можно ли избежать «гонки вывода»?

     http://www.google.co1m crawled by agent 1.  
     AgAAAent gent 3 is done.  
     gent 2 is done.  
     5 is done.  
     gent 4 is done.  
     Agent USupervisor RL collector is done.  
     is done.  
     1 is done.

[Изменить]

Последний вывод / сканирование все еще прекращается после использования обновления Томаса http://fssnip.net/65. Ниже приведен вывод программы после того, как я изменил «limit» на 5 и добавил несколько сообщений отладки.Последняя строка показывает усеченный URL.Можно ли определить, все ли сканеры закончили выполнение?

[Main] before crawl
[Crawl] before return result
http://news.google.com crawled by agent 1.
[supervisor] reached limit
http://www.gstatic.com/news/img/favicon.ico crawled by agent 5.
Agent 2 is done.
[supervisor] reached limit
Agent 5 is done.
http://www.google.com/imghp?hl=en&tab=ni crawled by agent 3.
[supervisor] reached limit
Agent 3 is done.
http://www.google.com/webhp?hl=en&tab=nw crawled by agent 4.
[supervisor] reached limit
Agent 4 is done.
http://news.google.com/n

Я изменил основной код на

printfn "[Main] before crawl"
crawl "http://news.google.com" 5
|> Async.RunSynchronously
printfn "[Main] after crawl"

Однако последний printfn "[Main]после сканирования " никогда не выполняется, если я не добавляю Console.Readline () в конце.

[Редактировать 2]

Код работает нормально под fsi.Однако у него будет такая же проблема, если он был запущен с использованием fsi --use: Program.fs --exec --quiet

1 Ответ

5 голосов
/ 02 июля 2011

Я создал фрагмент, который дополняет предыдущий двумя функциями, о которых вы спрашивали: http://fssnip.net/65.

  1. Чтобы решить эту проблему, я добавил Start сообщение, которое несет AsyncReplyChannel<unit>. Когда агент супервизора запускается, он ожидает это сообщение и сохраняет канал ответа для дальнейшего использования. По завершении он отправляет ответ по этому каналу.

    Функция, которая запускает агент, возвращает асинхронный рабочий процесс, ожидающий ответа. Затем вы можете позвонить crawl, используя Async.RunSynchronously, который завершится после завершения работы агента супервизора.

  2. Чтобы избежать гонок при печати, необходимо синхронизировать все отпечатки. Самый простой способ сделать это - написать нового агента :-). Агент получает строки и выводит их на выход один за другим (чтобы их нельзя было чередовать). Фрагмент скрывает стандартную функцию printfn с новой реализацией, которая отправляет агенту строки.

...