通过多个嵌套异步调用调试异常

时间:2016-04-19 20:25:13

标签: c# asynchronous exception-handling async-await

根据this question的答案,捕获异步方法抛出异常的表单如下所示:

public async void DoFoo()
{
    try
    {
        await Foo();
    }
    catch (ProtocolException ex)
    {
          /* The exception will be caught because you've awaited the call. */
    }
}

大。如果我想在几个级别的异步中冒泡,这似乎会瓦解。这是异常的起源:

internal static async Task MakePdfPagesFromPdf(Pdf pdf, byte[] pdfBytes, int jobId)
{
    IEnumerable<Image> pdfAsImages = PdfOperations.PdfToImagesPdfium(pdfBytes, dpi);

    if(pdfAsImages.Count() < 1)
    {
        throw new ArgumentException("PDF has no pages.");
    }

    // ... more code ...
}

以下是调用MakePdfPagesFromPdf的方法:

internal static async Task ProcessBase64Pdf(Pdf pdf, int jobId, string componentDesignName)
{
    byte[] pdfBytes = ConvertBase64ToPdfByteArray(pdf.Url); // Base64 data is in pdf.Url
    await UploadPdfToAwsS3(pdf, pdfBytes, jobId, componentDesignName);
    try
    {
        await MakePdfPagesFromPdf(pdf, pdfBytes, jobId);
    }
    catch(ArgumentException argumentException)
    {
        throw argumentException;
    }
}

我像本问题开头引用的例子一样捕获异常。调试断言此catch块被命中。但是,我需要将异常再增加一个级别,到控制器路径内:

try
{
    await PdfsController.ProcessBase64Pdf(pdf, componentDesign.JobId, componentDesign.Name);
}
catch (ArgumentException argumentException)
{
    // Now do stuff with the exception                  
}

在断点处没有达到这个最高级别的捕获量。去除中间捕获没有效果。路径继续并返回,但是在从中间ArgumentException抛出catch后,我无法命中断点。这里发生了什么,我如何通过整个异步堆栈来查找断点?

2 个答案:

答案 0 :(得分:1)

如果您要传播异常的方法是message(例如在async void的示例中),则问题是没有DoFoo个对象要传播异常(由于方法为Task且未返回void

我建议的另一件事是不Task,而只是throw argumentException,因为前者失去了原始异常的调用堆栈

答案 1 :(得分:-1)

我猜参数异常是内部异常的一部分。并且不是抛出的异常。您应该将 catch (ArgumentException argumentException) 更改为 catch (ArgumentException exception) 以调用“所有”异常。