많은 중첩 된 AggregateExceptions

aggregateexception async-await c# entity-framework-core

문제

Entity Framework 7로 작업하면서 일부 linq에서 간단한 실수를했습니다 (Skip을 사용하고 OrderBy 절을 포함하는 것을 잊었습니다).

이것에 의해 던져진 예외에는 여러 중첩 된 집계 예외가 포함됩니다.

예외를 생성하고 catch하는 코드는 다음과 같습니다.

int[] newIds;
try
{
    newIds = await db.Products
        .Where(p => p.PortalId == portalId)
        .Skip(ids.ProductIds.Count) //Skip the rows already read
        .Take(takeTotal) //get the next block
        .Select(p => p.ProductId)
        .ToArrayAsync();
}
catch (AggregateException ex)
{
    Console.WriteLine(ex.Message);
    newIds = new int[] { };
}

위의 코드는 Asp.Net 5 WebApi 컨트롤러에서 호출되는 repo 클래스에 있습니다. 모든 통화 수준에서 비동기 대기가 사용됩니다.

그러나 이것에서 얻은 집계 예외는 (위의 catch 블록에서 직접 창으로 덤프됩니다.) :

System.AggregateException : 하나 이상의 오류가 발생했습니다. ---> System.AggregateException : 하나 이상의 오류가 발생했습니다. ---> System.AggregateException : 하나 이상의 오류가 발생했습니다. ---> System.AggregateException : 하나 이상의 오류가 발생했습니다. ---> System.AggregateException : 하나 이상의 오류가 발생했습니다. ---> System.AggregateException : 하나 이상의 오류가 발생했습니다. ---> System.InvalidOperationException : Skip 연산자가 포함 된 쿼리는 하나 이상의 OrderBy 작업을 포함해야합니다. Microsoft.Data.Entity.Relational.Query.Sql.DefaultSqlQueryGenerator.GenerateLimitOffset (SelectExpression selectExpression) Microsoft.Data.Entity.Relational.Query.Sql.DefaultSqlQueryGenerator.VisitSelectExpression (SelectExpression selectExpression) at Microsoft.Data.Entity.Relational.Query .Expressions.SelectExpression.Accept (ExpressionTreeVisitor visitor) Microsoft.Data.Entity.Relational.Query.Sql.DefaultSqlQueryGenerator.GenerateSql (SelectExpression selectExpression, IDictionary`2 parameterValues) 등

여기에서 실제 예외는 집계 예외 (6 개의 중첩 된 계층)의 전체 묶음으로 마무리되었습니다. 왜 집계 예외가 발생하는지 이해하지만 왜 그렇게 많은지 궁금합니다. 이전부터 예외를보고 컨트롤러 입력 점으로 다시 되돌아갔습니다.

이것이 비동기식 레이어의 결과일까요? (6 개가 많지 않다고 생각하십니까?) 아니면 EF7 구현에서 문제가 될 수 있습니까?

현재 EF 7 릴리스 7.0.0-beta4를 사용 중입니다.

수락 된 답변

으로 의 MSDN 페이지 Task<T> 을 설명하는에 의해 throw 모든 예외 Task 에 싸여있다 AggregateException 동작중인 코드에 던져지기 전에. 여러 레벨의 async / await를 사용하고 가능한 가장 낮은 레벨에서이 예외를 포착하지 않으면 다른 레벨을 버블 링 할 때마다 다시 랩핑되어 AggregateException 내부의 AggregateException 합니다. 잡기없이 기다리고있다.

또한 각 작업이 자체 작업으로 계산 될 수도 있습니다. 즉. 다른 작업을 추가 할 때마다 결과는 이전 작업에서 나오고 이전 작업을 기다리는 작업과 함께 다음 작업으로 돌아갑니다. 보세요:

newIds = await db.Products               // 1
    .Where(p => p.PortalId == portalId)  // 2
    .Skip(ids.ProductIds.Count)          // 3
    .Take(takeTotal)                     // 4
    .Select(p => p.ProductId)            // 5
    .ToArrayAsync();                     // 6

6 가지 레이어로 이전의 결과를 기다리고 있습니다. 여섯 개의 AggregateException 계층. 이제 예외는 여섯 번째 중 세 번째로 인해 발생하지만 오류의 특성상 EF가 전체 쿼리를 읽는 부분에서 발생했을 가능성이 높습니다. 그렇게하는 동안 EF는 ' 일치하지 않는 .Skip() .OrderBy() .

으로 스티븐 클리어 리는 일 동안, 코멘트에 생각 나게 await 반환 Task<T> , 그들은 또한 당신을 위해 풀기의 정도를 할, 그래서 await 꽤처럼 행동하지 않는 Task<T>.Result , 의미 await발생한다 실제 예외를 AggregateException 래핑하지 않고. 이 모든 것이 의미하는 바는 기껏해야 우리는 단지 반 (半分)의 대답만을 가지고 있습니다 (그것은 이미 받아 들여 졌음을 알기에 조금 어색합니다). 솔직히, 다른 사람들이 귀하의 질문을 건너 뛰지 않고 다른 사람들이 그 격차를 메울 수있는 것을 알고 있는지 알 수 있도록이 답을 수락하지 말 것을 제안합니다.


인기 답변

체인에서 호출되는 메소드의 양과 관련이 없습니다. ToArrayAsync를 호출하면됩니다.

문제는 Rx.NET에 있다고 생각합니다. 나는 그것을 고칠 풀 요청을 보냈다 : https://github.com/aspnet/EntityFramework/issues/2192

https://github.com/Reactive-Extensions/Rx.NET/pull/131/files




아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.