首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AggregateException处理

AggregateException处理
EN

Code Review用户
提问于 2016-02-19 08:52:31
回答 1查看 10.9K关注 0票数 4

如何处理AggregateException?在许多TPL或业务场景中,它确实很有用,但是处理是一个真正的痛苦。我定义了以下三个扩展来帮助我自己。它们可以这样使用:

代码语言:javascript
复制
try
{
  throw new AggregateException(
     new ArgumentException(), 
     new DivideByZeroException());
}
catch (AggregateException aex)
{   
  aex
     .Handle((ArgumentException ex) =>
     {
         Console.WriteLine(ex.Message);
     })
     .Handle((DivideByZeroException ex) =>
     {
         Console.WriteLine(ex.Message);
         throw ex;
     })
     .Throw<DivideByZeroException>()
     .Throw<ArgumentException>()
     .ThrowIfNonEmpty();
}

这些方法是在AggregateException上定义的,并返回AggregateException,这样就可以将它们链接起来。

Handle为指定类型的每个内部异常实例调用一次参数委托,并返回一个AggregateException的新副本,而不包含那些已处理的异常。在委托中抛出的一个可选异常将添加到结果AggregateException中。

Throw方法尝试查找指定类型的第一个内部异常实例,并在找到时抛出它。你可以把他们锁在一起来决定优先权。

ThrowIfNonEmpty扩展了一个AggregateException,以便在InnerExceptions集合不是空时抛出它。

代码语言:javascript
复制
public static class AggregateExceptionExtensions
{
    public static AggregateException Handle<TEx>(
        this AggregateException source, Action<TEx> handler)
        where TEx : Exception
    {
        var exceptions = source.Flatten().InnerExceptions.OfType<TEx>();
        var handlerExceptions = new List<Exception>();
        foreach (var exception in exceptions)
            try
            {
                handler(exception);
            }
            catch (Exception ex)
            {
                handlerExceptions.Add(ex);
            }

        return new AggregateException(source.InnerExceptions
            .Except(exceptions)
            .Concat(handlerExceptions));
    }

    public static AggregateException Throw<TEx>(this AggregateException source)
    {
        var ex = source.InnerExceptions.FirstOrDefault(e => e is TEx);
        if (ex != null)
            throw ex;

        return source;
    }

    public static void ThrowIfNonEmpty(this AggregateException source)
    {
        if (source.InnerExceptions.Any())
            throw source;
    }
}

你能提出其他可能有用的窍门吗?

EN

回答 1

Code Review用户

回答已采纳

发布于 2016-09-04 04:07:15

我不认为只重新抛出特定类型的第一个/单个异常是个好主意。通常,当正确处理时,每个异常可能包含不同的错误数据,比如多个实体可能会发生实体验证错误,或者可能找不到多个文件等。如果您只选择第一个,那么您将不知道其余的情况,下次您将应用崩溃。

HandleThrowIfNonEmpty都很好,但是Throw非常有害。

此外,我会将Handle更改为Func<TEx, bool>

代码语言:javascript
复制
public static AggregateException Handle<TEx>(
    this AggregateException source, Func<TEx, bool> handler)
    where TEx : Exception
{
    var exceptions = source.Flatten().InnerExceptions.OfType<TEx>();
    var handlerExceptions = new List<Exception>();
    foreach (var exception in exceptions)
    {
        try
        {
            if (!handler(exception)) 
            {
                handlerExceptions.Add(exception);
            }
        }
        catch (Exception ex)
        {
            handlerExceptions.Add(ex);
        }
    }
    return new AggregateException(source.InnerExceptions
        .Except(exceptions)
        .Concat(handlerExceptions));
}

因此,例如,我可以记录它,并且仍然可以说我没有通过返回false来处理它。

代码语言:javascript
复制
.Handle((ArgumentException ex) =>
{
   Console.WriteLine(ex.Message);
   return false;
})
票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/120503

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档