F#MailboxProcessor问题

ca9*_*3d9 3 f# multithreading asynchronous mailboxprocessor

我使用http://fssnip.net/3K中的代码创建了一个控制台程序.我发现了

  1. 我将在末尾添加"System.Console.ReadLine()|> ignore"以等待线程的完成.是否有可能告诉所有MailBoxProcessors已完成并且程序可以自行退出?

  2. 我试图将测试网址"www.google.com"更改为无效的网址,我得到了以下输出.是否有可能避免"输出竞赛"?

     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.

[编辑]

使用Tomas的更新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
Run Code Online (Sandbox Code Playgroud)

我将主要代码更改为

printfn "[Main] before crawl"
crawl "http://news.google.com" 5
|> Async.RunSynchronously
printfn "[Main] after crawl"
Run Code Online (Sandbox Code Playgroud)

但是,除非我在末尾添加Console.Readline(),否则永远不会执行最后一次printfn"爬网后[Main]".

[编辑2]

代码在fsi下运行正常.但是,如果使用fsi --use:Program.fs --exec --quiet运行它将会遇到同样的问题

Tom*_*cek 5

我创建了一个片段,扩展了前一个片段,其中包含您提到的两个功能:http://fssnip.net/65.

  1. 为了解决这个问题,我添加Start了携带的消息AsyncReplyChannel<unit>.当主管代理启动时,它会等待此消息并保存回复通道供以后使用.完成后,它会使用此频道发送回复.

    启动代理程序的函数返回等待回复的异步工作流程.然后,您可以crawl使用Async.RunSynchronously,这将在主管代理完成时完成.

  2. 要在打印时避免竞争,您需要同步所有打印件.最简单的方法是编写一个新代理:-).代理接收字符串并逐个将它们打印到输出(这样它们就不能交错).该代码段隐藏了标准printfn函数,其中包含一个向代理发送字符串的新实现.