Flattening of AggregateExceptions for Processing

前端 未结 5 841
暖寄归人
暖寄归人 2020-12-10 01:46

I\'m running into a few issues where I call flatten on an AggregateException, but inside there is still ANOTHER AggregateException! T

5条回答
  •  余生分开走
    2020-12-10 02:07

    This is an old question, but the problem experienced by the OP is that await does not expose the AggregateException from the awaited task, but instead just the first exception in the AggregateException. So the catch(AggregateException ex) block is bypassed and the exception is caught further up the stack. So the code should have been 'simply':

    retryNeeded = false;
    do
    {
        try
        {
            if (retryNeeded)
                await Task.Delay(500); // substituted for Thread.Sleep
    
            using (var stream = file.Open(FileMode.Append, FileAccess.Write, FileShare.None))
            {
                using (StreamWriter writer = new StreamWriter(stream))
                {
                    await writer.WriteLineAsync(data);
                    retryNeeded = false;
                }
            }
        }
        catch (IOException)
        {
            retryNeeded = true;
            retryLeft--;
        }
        catch (Exception ex)
        {
            logger.ErrorException("Could not write to exception file: " + data, ex);
            throw;
        }
    } while (retryNeeded && retryLeft > 0);
    
    return (retryLeft > 0);
    

    Alternatively, Jon Skeet's WithAllExceptions extension method allows one to 'protect' the AggregateException from await's behavior by wrapping the task in another task so you get an AggregateException containing an AggregateException and await 'returns' the original/inner AggregateException.

    NOTE: AggregateException.Flatten really does 'flatten' recursively, as is shown by the example on the MSDN page.

    EDIT: Improved delay on retryNeeded to avoid setting a bad async example.

提交回复
热议问题