【发布时间】:2019-09-04 08:13:19
【问题描述】:
我正在编写的网络爬虫中使用 ActionBlock。
有时当我打电话时
actionBlock.Completion.Wait();
我收到以下错误
发生了一个或多个错误。
内部异常是
System.Threading.Tasks.TaskCanceledException:任务被取消。
这是下面的完整代码块。
actionBlock = new ActionBlock<URLsToCheckObject>(URLToCheck =>
{
try
{
// get more urls etc here and post below
actionBlock.Post(new URLsToCheckObject { URLAddress = CleanURL, Host = host });
if (actionBlock.InputCount == 0) actionBlock.Complete();
}
catch (Exception ex)
{
try
{
Logger.AddToDebugLog("Block 3 catch...", WebsiteToCrawl);
}
catch { }
}
}, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 3, CancellationToken = cancellationSource.Token });
actionBlock.Post(new URLsToCheckObject { URLAddress = WebsiteToCrawl.website, Host = host });
try
{
Logger.AddToDebugLog("Waiting on action block..", WebsiteToCrawl);
actionBlock.Completion.Wait();
}
catch (Exception ex)
{
try
{
Logger.AddToDebugLog("Block 4 catch..." + ex.Message, WebsiteToCrawl);
}
catch { }
try
{
Logger.AddToDebugLog("Block 4 catch..." + ex.InnerException, WebsiteToCrawl);
}
catch { }
try
{
Logger.AddToDebugLog("Block 4 catch...", WebsiteToCrawl);
}
catch { }
}
为什么包装ActionBlock 的全部内容的try/catch 不能捕捉到这个异常?
【问题讨论】:
-
您正在其自己的委托中操纵
ActionBlock。我不认为这个类被设计成这样使用。如果您想创建一个循环,其中管道的末端向管道添加更多元素,您可能应该在ActionBlock之前使用链接的BufferBlock,并将ActionBlock发布到BufferBlock。 -
@jamie 这不是 Dataflow 块应该如何工作。这段代码本质上是一个无限循环,它将 ActionBlock 视为一个队列。您不会告诉块从 内部 完成,它会在上游块完成时自动完成。如果要生成更多 URL,请在上一步中进行。代码根本不必那么复杂
标签: c# task-parallel-library tpl-dataflow