如何正确地从任务中冒出异常

And*_*ndy 1 .net c# exception task async-await

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

这是我的代码:

    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));
    }
Run Code Online (Sandbox Code Playgroud)

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

Ste*_*ary 5

不要使用ContinueWithawait代替使用。对于大多数异步代码来说,这是一个很好的一般规则。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;
}
Run Code Online (Sandbox Code Playgroud)