尝试使用异步 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
达到或系统内存不足?