Потенциальные проблемы с приведением IQueryable <T>к IAsyncEnumerable <T> - PullRequest
0 голосов
/ 18 октября 2019

После прочтения этой статьи о чрезмерном await использовании я решил убрать ожидание, где это возможно. Это привело к проблеме с моими службами данных по двум причинам:

  1. Все методы, которые получают коллекцию, возвращают Task<IEnumerable<T>> по соглашению
  2. EF не обеспечивает ToEnumerableAsync.

Теперь, когда я удаляю await, компилятор больше не разворачивает Task объекты, и у меня остается ошибка компиляции, которая говорит, что Task<List<T>> нельзя преобразовать в Task<IEnumerable<T>>.

Поэтому я решил создать свой собственный ToEnumerableAsnyc. Версия "PoC" выглядела так:

public static IEnumerable<T> ToEnumerableAsync<T>(this IQueryable<T> source)
    => (await source.ToListAsync()).AsEnumerable();

Однако это только обертывает лишние await и не удаляет их, то есть все еще есть мой await и тот, который использовался внутренне из ToListAsync,Насколько я понимаю из приведенной выше статьи, это создает ненужные накладные расходы. Это не важно, но накладные расходы, тем не менее. Пожалуйста, исправьте меня, если я ошибаюсь:)

Поэтому я решил выяснить, как разработчики Microsoft собирались реализовать ToListAsync в ASP.NET Core 2.2 , и мне удалось создать свой собственныйреализация ToEnumerableAsync, которая не использует await в зависимости от их решения. Вот как это выглядит:

public static Task<IEnumerable<T>> ToEnumerableAsync<T>(this IQueryable<T> queryable)
{
    var asyncEnum = AsAsyncEnumerable(queryable);
    var list = new List<T>();

    return asyncEnum.Aggregate(
        (IEnumerable<T>)list,
        (list, x) =>
        {
            ((List<T>)list).Add(x);
            return list;
        });
}

private static IAsyncEnumerable<T> AsAsyncEnumerable<T>(this IQueryable<T> queryable)
{
    if (queryable is IAsyncEnumerable<T> asyncEnumerable)
    {
        return asyncEnumerable;
    }

    throw new InvalidOperationException(
        $"Cannot cast \"IQueryable\" to \"IAsyncEnumerable\". Type: \"{typeof(T).FullName}\"");
}

И, наконец, на мой вопрос: что может пойти не так с приведением от IQueryable<T> к IAsyncEnumerable<T>, которое разработчики явно указали InvalidOperationExeption? Как и почему IQueryable<T> не может привести к IAsyncEnumerable<T>?

Исходный файл EF: QueriableExtensions.cs .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...