.NET용 Azure SDK를 사용한 페이지 매김
이 문서에서는 .NET용 Azure SDK 페이지 매김 기능을 사용하여 대량의 데이터 세트를 효율적이고 생산적으로 작업하는 방법을 알아봅니다. 페이지 매김은 대량의 데이터 세트를 페이지로 나눠 소비자가 더 적은 양의 데이터를 더 쉽게 반복할 수 있도록 하는 동작입니다. C# 8부터 비동기 스트림을 사용하여 스트림을 비동기적으로 만들고 사용할 수 있습니다. 비동기 스트림은 IAsyncEnumerable<T> 인터페이스를 기반으로 합니다. .NET용 Azure SDK는 AsyncPageable<T>
클래스를 사용하여 IAsyncEnumerable<T>
의 구현을 노출합니다.
이 문서의 모든 샘플은 다음 NuGet 패키지를 사용합니다.
- Azure.Security.KeyVault.Secrets
- Microsoft.Extensions.Azure
- Microsoft.Extensions.Hosting
- System.Linq.Async
.NET용 Azure SDK 패키지의 최신 디렉터리는 Azure SDK 최신 릴리스를 참조하세요.
Pageable 반환 형식
.NET용 Azure SDK에서 인스턴스화된 클라이언트는 다음과 같은 Pageable 형식을 반환할 수 있습니다.
Type | 설명 |
---|---|
Pageable<T> |
페이지에서 검색된 값 컬렉션 |
AsyncPageable<T> |
페이지에서 비동기적으로 검색된 값 컬렉션 |
이 문서의 샘플 대부분은 AsyncPageable<T>
형식의 변형을 사용하는 비동기적입니다. I/O 바인딩된 작업에는 비동기 프로그래밍을 사용하는 것이 바람직합니다. 완벽한 사용 사례는 .NET용 Azure SDK의 비동기 API를 사용하는 것인데, 이러한 작업은 HTTP/S 네트워크 호출을 나타내기 때문입니다.
await foreach
를 사용하여 AsyncPageable
반복
await foreach
구문을 사용하여 AsyncPageable<T>
를 반복하려면 다음 예제를 살펴보세요.
async Task IterateSecretsWithAwaitForeachAsync()
{
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
이 콘솔에 기록됩니다.
while
를 사용하여 AsyncPageable
반복
await foreach
구문을 사용할 수 없는 경우 AsyncPageable<T>
을 반복하려면 while
루프를 사용합니다.
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();
}
}
위의 C# 코드에서:
- SecretClient.GetPropertiesOfSecretsAsync 메서드가 호출되고
AsyncPageable<SecretProperties>
개체를 반환합니다. - AsyncPageable<T>.GetAsyncEnumerator 메서드가 호출되어
IAsyncEnumerator<SecretProperties>
를 반환합니다. - MoveNextAsync() 메서드는 반환할 항목이 없을 때까지 반복적으로 호출됩니다.
AsyncPageable
페이지 반복
서비스에서 값 페이지 수신을 제어하려면 AsyncPageable<T>.AsPages
메서드를 사용합니다.
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);
}
}
위의 C# 코드에서:
- SecretClient.GetPropertiesOfSecretsAsync 메서드가 호출되고
AsyncPageable<SecretProperties>
개체를 반환합니다. - AsyncPageable<T>.AsPages 메서드가 호출되고
IAsyncEnumerable<Page<SecretProperties>>
를 반환합니다. - 각 페이지는
await foreach
를 사용하여 비동기적으로 반복됩니다. - 각 페이지에는 동기
foreach
를 사용하여 반복되는IReadOnlyList<T>
를 나타내는 Page<T>.Values 세트가 있습니다. - 또한 각 페이지에는 다음 페이지를 요청하는 데 사용될 수 있는 Page<T>.ContinuationToken이 포함되어 있습니다.
AsyncPageable
에 System.Linq.Async
사용
System.Linq.Async
패키지는 IAsyncEnumerable<T> 형식에서 작동하는 LINQ 메서드 세트를 제공합니다. AsyncPageable<T>
이 IAsyncEnumerable<T>
을 구현하므로 System.Linq.Async
를 사용하여 데이터를 쿼리하고 변환할 수 있습니다.
List<T>
로 변환
ToListAsync
를 사용하여 AsyncPageable<T>
을 List<T>
로 변환합니다. 데이터가 단일 페이지로 반환되지 않는 경우 이 메서드를 수행하는 데 여러 번의 서비스 호출이 수행될 수 있습니다.
async Task ToListAsync()
{
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
는 AsyncPageable
의 처음 N
개 요소를 가져오는 데만 사용할 수 있습니다. Take
를 사용하면 N
개 항목을 가져오는 데 최소 서비스 호출 수가 필요합니다.
async Task TakeAsync(int count = 30)
{
AsyncPageable<SecretProperties> allSecrets =
client.GetPropertiesOfSecretsAsync();
await foreach (SecretProperties secret in allSecrets.Take(count))
{
Console.WriteLine($"TakeAsync: {secret.Name}");
}
}
추가 메서드
System.Linq.Async
는 동기 Enumerable
클래스와 같은 기능을 제공하는 다른 메서드를 제공합니다. 이러한 메서드의 예로는 Select
, Where
, OrderBy
, GroupBy
가 있습니다.
클라이언트 쪽 평가 주의
System.Linq.Async
패키지를 사용하는 경우 LINQ 작업이 클라이언트에서 실행되는지 주의해야 합니다. 다음 쿼리는 단지 개수를 세기 위해 ‘모든’ 항목을 페치합니다.
// ⚠️ DON'T DO THIS! 😲
int expensiveSecretCount =
await client.GetPropertiesOfSecretsAsync()
.CountAsync();
Warning
같은 경고가 Where
와 같은 연산자에도 적용됩니다. 사용 가능한 경우 항상 서버 쪽 데이터 필터링, 집계 또는 프로젝션을 사용하세요.
관찰 가능한 시퀀스로
System.Linq.Async
패키지는 주로 IAsyncEnumerable<T>
시퀀스에 관찰자 패턴 기능을 제공하는 데 사용됩니다. 비동기 스트림은 풀을 기반으로 합니다. 해당 항목이 반복되므로 사용 가능한 다음 항목이 ‘풀링’됩니다. 이 접근 방식은 푸시 기반의 관찰자 패턴과 병치됩니다. 항목이 사용 가능해지면 관찰자 역할을 하는 구독자에게 ‘푸시’됩니다. System.Linq.Async
패키지는 IAsyncEnumerable<T>
을 IObservable<T>
로 변환할 수 있는 ToObservable
확장 메서드를 제공합니다.
IObserver<SecretProperties>
구현을 상상해 보세요.
sealed file class SecretPropertyObserver : 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
확장 메서드를 사용할 수 있습니다.
IDisposable UseTheToObservableMethod()
{
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 반복
Pageable<T>
는 일반 foreach
루프와 함께 사용할 수 있는 AsyncPageable<T>
의 동기 버전입니다.
void IterateWithPageable()
{
Pageable<SecretProperties> allSecrets = client.GetPropertiesOfSecrets();
foreach (SecretProperties secret in allSecrets)
{
Console.WriteLine($"IterateWithPageable: {secret.Name}");
}
}
Important
이 동기 API를 사용할 수 있지만, 더 나은 환경을 위해 비동기 API 대안을 사용하세요.
참고 항목
.NET