이 문서에서는 Azure SDK for .NET 페이지 매김 기능을 사용하여 대규모 데이터 집합에서 효율적이고 생산적으로 작업하는 방법을 알아봅니다. 페이지 매김은 큰 데이터 집합을 페이지로 분할하여 소비자가 더 적은 양의 데이터를 더 쉽게 반복할 수 있도록 하는 작업입니다. C# 8부터 비동기 (비동기) 스트림을 사용하여 비동기적으로 스트림을 만들고 사용할 수 있습니다. 비동기 스트림은 IAsyncEnumerable<T> 인터페이스를 기반으로 합니다. .NET용 Azure SDK는 IAsyncEnumerable<T>
클래스를 사용하여 AsyncPageable<T>
의 구현을 제공합니다.
이 문서의 모든 샘플은 다음 NuGet 패키지를 사용합니다.
- Azure.Security.KeyVault.Secrets
- Microsoft.Extensions.Azure
- Microsoft.Extensions.Hosting
- System.Linq.Async
.NET 패키지용 Azure SDK의 최신 디렉터리에 대해서는 Azure SDK 최신 릴리스를 참조하세요.
페이지 가능 반환 형식
.NET용 Azure SDK에서 인스턴스화된 클라이언트는 다음 페이징 가능 형식을 반환할 수 있습니다.
유형 | 설명 |
---|---|
Pageable<T> |
페이지에서 검색된 값의 컬렉션 |
AsyncPageable<T> |
페이지에서 비동기적으로 검색된 값 컬렉션 |
이 문서의 샘플 대부분은 형식의 AsyncPageable<T>
변형을 사용하여 비동기적입니다. I/O 바인딩된 작업에 비동기 프로그래밍을 사용하는 것이 이상적입니다. 완벽한 사용 사례는 이러한 작업이 HTTP/S 네트워크 호출을 나타내기 때문에 .NET용 Azure SDK의 비동기 API를 사용하는 것입니다.
AsyncPageable
를 await foreach
로 반복하다
AsyncPageable<T>
을(를) await foreach
구문을 사용하여 반복하려면 다음 예제를 고려하세요.
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
이 콘솔에 기록됩니다.
AsyncPageable
를 while
로 반복하다
AsyncPageable<T>
반복을 await foreach
구문을 사용할 수 없는 경우 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
을 사용하여 비동기적으로 반복됩니다. - 각 페이지에는 Page<T>.Values의 집합이 있으며, 이는 동기
IReadOnlyList<T>
으로 반복되는foreach
을 나타냅니다. - 각 페이지에는 Page<T>.ContinuationToken다음 페이지를 요청하는 데 사용할 수 있는 이 항목도 포함되어 있습니다.
System.Linq.Async
를 AsyncPageable
과 함께 사용
System.Linq.Async
패키지는 형식에서 작동하는 IAsyncEnumerable<T> 메서드 집합을 제공합니다.
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
의 첫 번째 N
요소 AsyncPageable
만 가져오는 데 사용할 수 있습니다.
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();
경고
같은 연산자(예 Where
: .)에게도 동일한 경고가 적용됩니다. 사용 가능한 경우 항상 서버 쪽 필터링, 집계 또는 데이터 프로젝션을 선호합니다.
관찰 가능한 시퀀스로
패키지 System.Linq.Async
는 주로 시퀀스에 대한 IAsyncEnumerable<T>
관찰자 패턴 기능을 제공하는 데 사용됩니다. 비동기 스트림은 끌어오기 기반입니다. 항목이 반복되면 사용 가능한 다음 항목이 끌어옵니다. 이 방법은 푸시 기반 관찰자 패턴과 병치됩니다. 항목을 사용할 수 있게 되면 관찰자 역할을 하는 구독자에게 푸시 됩니다.
System.Linq.Async
패키지는 ToObservable
확장 메서드를 제공하여 IAsyncEnumerable<T>
를 IObservable<T>
로 변환할 수 있습니다.
구현을 상상해 보세요.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<T>
는 일반 AsyncPageable<T>
루프와 함께 사용할 수 있는 동기 버전 foreach
입니다.
void IterateWithPageable()
{
Pageable<SecretProperties> allSecrets = client.GetPropertiesOfSecrets();
foreach (SecretProperties secret in allSecrets)
{
Console.WriteLine($"IterateWithPageable: {secret.Name}");
}
}
중요합니다
이 동기 API를 사용할 수 있지만 더 나은 환경을 위해 비동기 API 대안을 사용합니다.
참고하십시오
.NET