繁体   English   中英

如何正确冒泡任务中的异常

[英]How to correctly bubble up exceptions from Tasks

我正在尝试编写一个异步方法,该方法从数据库中读取一个项目并在读取前后提供一定数量的验证。 快乐之路没问题,但我无法弄清楚如何正确抛出异常。

这是我的代码:

    protected override async Task<Entity> InternalRead<TEntity>(object id)
    {
        var result = this.context.Set<Entity>().FindAsync(id);
        return await result;
    }

    public Task<TEntity> Read<Entity>(object id) where TEntity : class
    {
        return InternalRead<Entity>(id)
            .ContinueWith(entityTask => 
            {
                var entity = entityTask.Result;
                if (entity != null && !entity.IsHidden)
                    throw new UnauthorizedAccessException();

                return entity;
            });
    }

    [Fact]
    public async Task InvalidIdThrowsExpectedException()
    {
        var db = *getDBCode*
        var identity = new Identity();
        await Assert.ThrowsAsync<UnauthorizedAccessException>(() => accessor.Read<TradingStyle>(1, identity));
    }

id 为1的实体是隐藏的,当我单步执行代码时,我可以看到按预期抛出了异常,但测试看到抛出了AggregateException而不是UnauthorizedAccessException 我看不出我的设置和我一直在阅读的示例之间有什么不同,但我很困惑为什么 Assert.ThrowAsync 没有展开内部异常。

不要使用ContinueWith 改用await 对于大多数异步代码来说,这是一个很好的通用规则。 ContinueWith是一种低级方法,具有令人惊讶的默认行为; await以您期望的方式工作:

public async Task<TEntity> Read<Entity>(object id) where TEntity : class
{
  var entity = await InternalRead<Entity>(id);
  if (entity != null && !entity.IsHidden)
    throw new UnauthorizedAccessException();

  return entity;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM