【问题标题】:F# MailboxProcessor questionsF# MailboxProcessor 问题
【发布时间】:2011-07-02 09:13:13
【问题描述】:

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

  1. 我要在末尾添加“System.Console.ReadLine() |> ignore”以等待线程完成。是否可以告诉所有 MailBoxProcessor 都已完成并且程序可以自行退出?

  2. 我尝试将测试 url “www.google.com”更改为无效的 url,并得到以下输出。是否可以避免“输出竞赛”?

代理 1 抓取的 http://www.google.co1m。 AgAAAent gent 3 完成。 绅士2完成了。 5 完成。 绅士4完成了。 代理 USupervisor RL 收集器完成。 已经完成了。 1 完成。

[编辑]

在使用 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

我把主代码改成

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

但是,最后一个 printfn "[Main] after crawl" 永远不会执行,除非我在最后添加一个 Console.Readline()。

[编辑 2]

代码在 fsi 下运行良好。但是,如果使用它运行它将有同样的问题 fsi --use:Program.fs --exec --quiet

【问题讨论】:

  • 对我来说,这种使用邮箱处理器来解决 URL 爬取的做法太复杂了,而且 URL 内容的获取也不是异步调用。使用简单的异步计算可以轻松解决该问题。

标签: multithreading asynchronous f# mailboxprocessor


【解决方案1】:

我创建了一个 sn-p,它使用您询问的两个功能扩展了前一个:http://fssnip.net/65

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

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

  2. 为避免打印时出现竞争,您需要同步所有打印。最简单的方法是编写一个新代理:-)。代理接收字符串并将它们一一打印到输出(这样它们就不会被交错)。 sn-p 隐藏了标准的printfn 函数,新实现将字符串发送到代理。

【讨论】:

  • 非常感谢。我编译了代码并在控制台窗口中运行它。但是,通常有一个代理无法完成。例如,代理 1 已完成。 google.com/accounts/… 已被代理 5 抓取。代理 5 已完成。 google.com/reader/?tab=ny 已被代理 4 抓取。代理 4 已完成。 groups.google.com/grphp?hl=en&tab=ng 已被代理 3 抓取。代理 3 已完成。 sites.g C:\Users\nick\Documents\Visual Studio 2010\Projects\WebCrawler\WebCrawler\bin\Debug>
  • 评论里的格式好像搞错了。问题是最后一个输出被截断。例如,方括号中的字符可能会被截断。 groups.go[ogle.com/grphp?hl=en&tab=ng被代理N爬取。]
猜你喜欢
  • 2014-05-22
  • 2018-10-12
  • 1970-01-01
  • 2021-06-17
  • 1970-01-01
  • 1970-01-01
  • 2017-06-26
  • 1970-01-01
  • 2019-06-08
相关资源
最近更新 更多