c# - 为什么ActionBlock中的Try/catch有时抓不到这个错误?

标签 c# task-parallel-library tpl-dataflow

我正在编写的网络爬虫中使用 ActionBlock。

有时候打电话

actionBlock.Completion.Wait();

出现以下错误

One or more errors occurred.

内部异常是

System.Threading.Tasks.TaskCanceledException: A task was canceled.

这是下面的完整代码块。

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 没有捕捉到这个异常?

最佳答案

异常通常来自:

cancellationToken.ThrowIfCancellationRequested();

因为您没有在 lambda 中使用 CancellationToken,但它用作以下参数:

new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 3, CancellationToken = cancellationSource.Token }

TaskCanceledException 不是来自您的 lambda(但可能来自 ExecutionDataflowBlockOptionsActionBlock 内部),因此它超出了您的范围try/catch 在 lambda 内部,因此它不会捕获。

关于c# - 为什么ActionBlock中的Try/catch有时抓不到这个错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57784167/

相关文章:

c# - 一起运行两个 parallel.foreach()

c# - TPL 数据流 - 非常快的生产者,不是那么快的消费者 OutOfMemory 异常

.net - TPL 数据流 : What's the difference between these 2 code snippets?

c# - 我可以使用显式运算符来创建派生类吗?

c# - 如何使用 JSON 对象通过 postman 发布到 MVC 端点

c# - Linux Entity Framework Core 上的无效 SQL Server 连接字符串

c# - 了解 WebClient UploadString() 与 UploadStringTaskAsync 的异步

c# - AttachedToParent 有哪些用例?

c# - 如何为 WMI 查询设置超时?

.net - 使用 TransformBlock 捕获原始异常