Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этой статье вы узнаете, как использовать функциональность пагинации в пакете SDK Azure для .NET для эффективной и продуктивной работы с большими наборами данных. Разбиение на страницы — это процесс деления больших наборов данных на страницы, что позволяет пользователю проще работать с меньшим объемом данных. Начиная с C# 8, можно создавать и использовать потоки асинхронно с помощью асинхронных (асинхронных) потоков. Асинхронные потоки основаны на интерфейсе IAsyncEnumerable<T> . Пакет SDK Azure для .NET предоставляет реализацию IAsyncEnumerable<T> при помощи класса AsyncPageable<T>.
Все примеры из этой статьи основаны на следующих пакетах NuGet:
- Azure.Security.KeyVault.Secret
- Microsoft.Extensions.Azure
- Microsoft.Extensions.Hosting
- System.Linq.Async
Последний каталог пакетов Azure SDK для .NET см. в последних выпусках пакета Azure SDK.
Типы возвращаемых объектов с пагинацией
Клиенты, созданные с использованием Azure SDK для .NET, могут возвращать следующие страницируемые типы данных.
| Тип | Описание |
|---|---|
Pageable<T> |
Коллекция значений, полученных на страницах |
AsyncPageable<T> |
Коллекция значений, асинхронно извлекаемых на страницах |
Большинство примеров в этой статье являются асинхронными, используя варианты AsyncPageable<T> типа. Использование асинхронного программирования для операций с привязкой ввода-вывода идеально подходит. Идеальный вариант использования — использование асинхронных API из пакета SDK Azure для .NET, так как эти операции представляют сетевые вызовы HTTP/S.
Итерировать по AsyncPageable с помощью await foreach
Чтобы выполнить итерацию по AsyncPageable<T> с использованием синтаксиса await foreach, рассмотрим следующий пример:
{
AsyncPageable<SecretProperties> allSecrets = client.GetPropertiesOfSecretsAsync();
await foreach (SecretProperties secret in allSecrets)
{
Console.WriteLine($"IterateSecretsWithAwaitForeachAsync: {secret.Name}");
}
}
В приведенном выше коде C#:
- Метод SecretClient.GetPropertiesOfSecretsAsync вызывается и возвращает
AsyncPageable<SecretProperties>объект. - В цикле
await foreachкаждый элементSecretPropertiesасинхронно передается. - Когда каждый
secretматериализуется, егоNameзаписывается в консоль.
Итерировать по AsyncPageable с помощью while
Чтобы выполнить итерацию по AsyncPageable<T>, когда синтаксис await foreach недоступен, используйте цикл while.
{
AsyncPageable<SecretProperties> allSecrets = client.GetPropertiesOfSecretsAsync();
IAsyncEnumerator<SecretProperties> enumerator = allSecrets.GetAsyncEnumerator();
try
{
while (await enumerator.MoveNextAsync())
{
SecretProperties secret = enumerator.Current;
Console.WriteLine($"IterateSecretsWithWhileLoopAsync: {secret.Name}");
}
}
finally
{
await enumerator.DisposeAsync();
}
}
В приведенном выше коде C#:
- Метод SecretClient.GetPropertiesOfSecretsAsync вызывается и возвращает
AsyncPageable<SecretProperties>объект. - Метод AsyncPageable<T>.GetAsyncEnumerator вызывается, возвращая объект
IAsyncEnumerator<SecretProperties>. - Метод MoveNextAsync() вызывается многократно, пока не останется элементов для возврата.
Итерируйте по AsyncPageable страницам
Если вы хотите контролировать получение страниц значений из службы, используйте метод AsyncPageable<T>.AsPages:
{
AsyncPageable<SecretProperties> allSecrets = client.GetPropertiesOfSecretsAsync();
await foreach (Page<SecretProperties> page in allSecrets.AsPages())
{
foreach (SecretProperties secret in page.Values)
{
Console.WriteLine($"IterateSecretsAsPagesAsync: {secret.Name}");
}
// The continuation token that can be used in AsPages call to resume enumeration
Console.WriteLine(page.ContinuationToken);
}
}
В приведенном выше коде C#:
- Метод SecretClient.GetPropertiesOfSecretsAsync вызывается и возвращает
AsyncPageable<SecretProperties>объект. - Метод AsyncPageable<T>.AsPages вызывается и возвращается
IAsyncEnumerable<Page<SecretProperties>>. - Каждая страница проходит итерацию асинхронно, используя
await foreach. - Каждая страница содержит набор Page<T>.Values, представляющий
IReadOnlyList<T>, над которым выполняется синхронная итерация с помощьюforeach. - Каждая страница также содержит объект Page<T>.ContinuationToken, который можно использовать для запроса следующей страницы.
Используйте System.Linq.Async с AsyncPageable
Пакет System.Linq.Async предоставляет набор методов LINQ , работающих с IAsyncEnumerable<T> типом. Так как AsyncPageable<T> реализуется IAsyncEnumerable<T>, можно использовать System.Linq.Async для запроса и преобразования данных.
Конвертировать в List<T>
Используйте ToListAsync для преобразования AsyncPageable<T> в List<T>. Этот метод может вызывать несколько вызовов служб, если данные не возвращаются на одной странице.
{
AsyncPageable<SecretProperties> allSecrets =
client.GetPropertiesOfSecretsAsync();
List<SecretProperties> secretList = await allSecrets.ToListAsync();
secretList.ForEach(secret =>
Console.WriteLine($"ToListAsync: {secret.Name}"));
}
В приведенном выше коде C#:
- Метод SecretClient.GetPropertiesOfSecretsAsync вызывается и возвращает
AsyncPageable<SecretProperties>объект. - Ожидается метод
ToListAsync, который создает новый экземплярList<SecretProperties>.
Возьмите первые N-элементы
Take можно использовать для получения только первых N элементов из AsyncPageable. Использование Take потребует минимальное количество вызовов службы для получения N элементов.
{
AsyncPageable<SecretProperties> allSecrets =
client.GetPropertiesOfSecretsAsync();
await foreach (SecretProperties secret in allSecrets.Take(count))
{
Console.WriteLine($"TakeAsync: {secret.Name}");
}
}
Дополнительные методы
System.Linq.Async предоставляет другие методы, которые предоставляют функциональные возможности, эквивалентные их синхронным Enumerable аналогам. Примеры таких методов: Select, Whereи OrderByGroupBy.
Осторожно: вычисления на клиентской стороне
При использовании System.Linq.Async пакета убедитесь, что операции LINQ выполняются на клиенте. Следующий запрос будет получить все элементы только для их подсчета:
// ⚠️ DON'T DO THIS! 😲
int expensiveSecretCount =
await client.GetPropertiesOfSecretsAsync()
.CountAsync();
Предупреждение
Такое же предупреждение применяется к операторам, таким как Where. Всегда предпочитайте фильтрацию на стороне сервера, агрегирование или проекции данных, если они доступны.
Как наблюдаемая последовательность
Пакет System.Linq.Async в основном используется для предоставления возможностей шаблона наблюдателя для IAsyncEnumerable<T> последовательностей. Асинхронные потоки работают по принципу вытягивания. По мере итерации элементов следующий доступный элемент извлекается. Этот подход находится в противопоставлении с шаблоном наблюдателя, который использует технологию push. По мере того как элементы становятся доступными, они передаются подписчикам, которые действуют как наблюдатели. Пакет System.Linq.Async предоставляет метод расширения ToObservable, который позволяет преобразовать IAsyncEnumerable<T> в IObservable<T>.
Представьте реализацию IObserver<SecretProperties> :
{
public void OnCompleted() =>
Console.WriteLine("Done observing secrets");
public void OnError(Exception error) =>
Console.WriteLine($"Error observing secrets: {error}");
public void OnNext(SecretProperties secret) =>
Console.WriteLine($"Observable: {secret.Name}");
}
Можно использовать метод расширения ToObservable следующим образом:
{
AsyncPageable<SecretProperties> allSecrets =
client.GetPropertiesOfSecretsAsync();
IObservable<SecretProperties> observable = allSecrets.ToObservable();
return observable.Subscribe(
new SecretPropertyObserver());
}
В приведенном выше коде C#:
- Метод SecretClient.GetPropertiesOfSecretsAsync вызывается и возвращает
AsyncPageable<SecretProperties>объект. - Метод
ToObservable()вызывается в экземпляреAsyncPageable<SecretProperties>, возвращая объектIObservable<SecretProperties>. - На
observableоформляется подписка, передаётся реализация наблюдателя, и эта подписка возвращается вызывающей стороне. - Подписка — это
IDisposable. После удаления подписка заканчивается.
Итерации по страницам
Pageable<T> — синхронная версия AsyncPageable<T> , которую можно использовать с обычным foreach циклом.
{
Pageable<SecretProperties> allSecrets = client.GetPropertiesOfSecrets();
foreach (SecretProperties secret in allSecrets)
{
Console.WriteLine($"IterateWithPageable: {secret.Name}");
}
}
Это важно
Хотя этот синхронный API доступен, используйте асинхронные альтернативные варианты API для лучшего взаимодействия.