# Pagination with the Azure SDK for .NET

In this article, you'll learn how to use the Azure SDK for .NET pagination functionality to work efficiently and productively with large data sets. Pagination is the act of dividing large data sets into pages, making it easier for the consumer to iterate through smaller amounts of data. Starting with C# 8, you can create and consume streams asynchronously using Asynchronous (async) streams. Async streams are based on the IAsyncEnumerable<T> interface. The Azure SDK for .NET exposes an implementation of IAsyncEnumerable<T> with its AsyncPageable<T> class.

All of the samples in this article rely on the following NuGet packages:

For the latest directory of Azure SDK for .NET packages, see Azure SDK latest releases.

## Pageable return types

Clients instantiated from the Azure SDK for .NET can return the following pageable types.

Type Description
Pageable<T> A collection of values retrieved in pages
AsyncPageable<T> A collection of values asynchronously retrieved in pages

Most of the samples in this article are asynchronous, using variations of the AsyncPageable<T> type. Using asynchronous programming for I/O-bound operations is ideal. A perfect use case is using the async APIs from the Azure SDK for .NET as these operations represent HTTP/S network calls.

## Iterate over AsyncPageable with await foreach

To iterate over an AsyncPageable<T> using the await foreach syntax, consider the following example:

async Task IterateSecretsWithAwaitForeachAsync()
{
AsyncPageable<SecretProperties> allSecrets = client.GetPropertiesOfSecretsAsync();

await foreach (SecretProperties secret in allSecrets)
{
Console.WriteLine($"IterateSecretsWithAwaitForeachAsync: {secret.Name}"); } }  In the preceding C# code: • The SecretClient.GetPropertiesOfSecretsAsync method is invoked and returns an AsyncPageable<SecretProperties> object. • In an await foreach loop, each SecretProperties is asynchronously yielded. • As each secret is materialized, its Name is written to the console. ## Iterate over AsyncPageable with while To iterate over an AsyncPageable<T> when the await foreach syntax isn't available, use a while loop. async Task IterateSecretsWithWhileLoopAsync() { 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();
}
}


In the preceding C# code:

## Iterate over AsyncPageable pages

If you want control over receiving pages of values from the service, use the AsyncPageable<T>.AsPages method:

async Task IterateSecretsAsPagesAsync()
{
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); } }  In the preceding C# code: • The SecretClient.GetPropertiesOfSecretsAsync method is invoked and returns an AsyncPageable<SecretProperties> object. • The AsyncPageable<T>.AsPages method is invoked and returns an IAsyncEnumerable<Page<SecretProperties>>. • Each page is iterated over asynchronously, using await foreach. • Each page has a set of Page<T>.Values, which represents an IReadOnlyList<T> that's iterated over with a synchronous foreach. • Each page also contains a Page<T>.ContinuationToken, which can be used to request the next page. ## Use System.Linq.Async with AsyncPageable The System.Linq.Async package provides a set of LINQ methods that operate on IAsyncEnumerable<T> type. Because AsyncPageable<T> implements IAsyncEnumerable<T>, you can use System.Linq.Async to query and transform the data. ### Convert to a List<T> Use ToListAsync to convert an AsyncPageable<T> to a List<T>. This method might make several service calls if the data isn't returned in a single page. async Task ToListAsync() { AsyncPageable<SecretProperties> allSecrets = client.GetPropertiesOfSecretsAsync(); List<SecretProperties> secretList = await allSecrets.ToListAsync(); secretList.ForEach(secret => Console.WriteLine($"ToListAsync: {secret.Name}"));
}


In the preceding C# code:

• The SecretClient.GetPropertiesOfSecretsAsync method is invoked and returns an AsyncPageable<SecretProperties> object.
• The ToListAsync method is awaited, which materializes a new List<SecretProperties> instance.

### Take the first N elements

Take can be used to get only the first N elements of the AsyncPageable. Using Take will make the fewest service calls required to get N items.

async Task TakeAsync(int count = 30)
{
AsyncPageable<SecretProperties> allSecrets = client.GetPropertiesOfSecretsAsync();

await foreach (SecretProperties secret in allSecrets.Take(count))
{
public void OnNext(SecretProperties secret) => Console.WriteLine($"Observable: {secret.Name}"); }  You could consume the ToObservable extension method as follows: IDisposable UseTheToObservableMethod() { AsyncPageable<SecretProperties> allSecrets = client.GetPropertiesOfSecretsAsync(); IObservable<SecretProperties> observable = allSecrets.ToObservable(); return observable.Subscribe(new SecretPropertyObserver()); }  In the preceding C# code: • The SecretClient.GetPropertiesOfSecretsAsync method is invoked and returns an AsyncPageable<SecretProperties> object. • The ToObservable() method is called on the AsyncPageable<SecretProperties> instance, returning an IObservable<SecretProperties>. • The observable is subscribed to, passing in the observer implementation, returning the subscription to the caller. • The subscription is an IDisposable. When it's disposed, the subscription ends. ## Iterate over pageable Pageable<T> is a synchronous version of AsyncPageable<T> that can be used with a normal foreach loop. void IterateWithPageable() { Pageable<SecretProperties> allSecrets = client.GetPropertiesOfSecrets(); foreach (SecretProperties secret in allSecrets) { Console.WriteLine($"IterateWithPageable: {secret.Name}");
}
}


Important

While this synchronous API is available, use the asynchronous API alternatives for a better experience.