0
我有一段代码,看起来像这样:WebException不会在它应该出现的位置?
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;
}
但是为什么我的try块没有捕获它呢?
如果我去了它指向的调用堆栈这一行:
foreach (var node in sq.Find("a[href]"))
但sq.Find
甚至不触及任何网络接口。这是怎么回事?
这些线是同步的,
using (var str = wc.OpenRead(uri))
doc.Load(str);
不是吗?加载完成后不应该导致错误发生。
因为它是一个可枚举的,呃?没有意识到他们是这样工作的。调用'.ToArray()'或其他东西会强制它评估,不是吗? – mpen 2010-09-27 07:33:08
是的,或者你可以将每个移动到try块(如果这是访问它) – 2010-09-27 07:40:12
是的...... foreach是什么导致访问/评估,但我想我宁愿赶上错误提前,它实际上正在发生,而不是在某个时候。这真的很疯狂,但是你可以传播这样的错误。循环遍历一个枚举似乎应该是安全的。 – mpen 2010-09-27 07:46:56