【发布时间】:2012-02-13 11:28:27
【问题描述】:
尝试使用 Async CTP 编写 HTML 爬虫,但我一直不知道如何编写无递归方法来完成此任务。
这是我目前的代码。
private readonly ConcurrentStack<LinkItem> _LinkStack;
private readonly Int32 _MaxStackSize;
private readonly WebClient client = new WebClient();
Func<string, string, Task<List<LinkItem>>> DownloadFromLink = async (BaseURL, uri) =>
{
string html = await client.DownloadStringTaskAsync(uri);
return LinkFinder.Find(html, BaseURL);
};
Action<LinkItem> DownloadAndPush = async (o) =>
{
List<LinkItem> result = await DownloadFromLink(o.BaseURL, o.Href);
if (this._LinkStack.Count() + result.Count <= this._MaxStackSize)
{
this._LinkStack.PushRange(result.ToArray());
o.Processed = true;
}
};
Parallel.ForEach(this._LinkStack, (o) =>
{
DownloadAndPush(o);
});
但显然这并不像我希望的那样有效,因为在Parallel.ForEach 执行第一次(也是唯一一次迭代)时,我只有一项。我能想到的使ForEach 递归的最简单方法,但我不能(我不认为)这样做,因为我会很快耗尽堆栈空间。
谁能指导我如何重构此代码,以创建我将描述为添加项目的递归延续,直到达到MaxStackSize 或系统内存不足?
【问题讨论】:
-
+1。谁控制了递归,谁就控制了宇宙!
标签: c# .net multithreading async-ctp async-await