我有一大堆代码看起来像这样:
var task = Task.Factory.StartNew(() =>
{
while (!bc.IsCompleted && !cts.Token.IsCancellationRequested)
{
PriorityDownloadPair pd;
if (bc.TryTake(out pd))
{
var baseUri = pd.Value.Uri;
Console.WriteLine("({0}) {1}", pd.Key, baseUri.AbsoluteUri);
IEnumerable<HtmlNode> sq = null;
try
{
sq = SharpQuery.SharpQuery.Load(baseUri);
}
catch (WebException we)
{
Console.WriteLine(we.Message);
continue;
}
foreach (var node in sq.Find("a[href]"))
{
bc.Add(new PriorityDownloadPair(1, new DownloadItem { Uri = new Uri(baseUri, node.Attributes["href"].Value) }));
}
}
}
}, cts.Token);
它可以运行一段时间(跟随并下载它找到的每个链接),直到它到达404.
404正如我所期望的那样在SharpQuery.Load方法中出现:
public static IEnumerable<HtmlNode> Load(Uri uri)
{
var doc = new HtmlDocument();
WebClient wc = new WebClient();
using (var str = wc.OpenRead(uri))
doc.Load(str);
yield return doc.DocumentNode;
}
但是为什么我的尝试阻止它不是为了捕捉它?
如果我向上调用堆栈,则指向此行:
foreach (var node in sq.Find("a[href]"))
但sq.Find
甚至没有触及任何网络界面。发生了什么事?
这些行是同步的,
using (var str = wc.OpenRead(uri))
doc.Load(str);
不是吗?它装完后不应该导致错误吗?
答案 0 :(得分:1)
这是因为在您实际读取数据之后才会执行加载,这是在try块之后。