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
アイテムが 1 つしかないため、明らかにこれは期待どおりには機能しません。再帰的に考えることができる最も簡単なアプローチですがForEach
、スタックスペースがすぐに不足するため、これを行うことはできません(私は考えていません)。
このコードを再構築する方法を教えてください。にMaxStackSize
到達するか、システムがメモリ不足になるまでアイテムを追加する再帰的な継続として説明するものを作成しますか?