共用方式為


使用適用於 .NET 的 Azure SDK 進行分頁

在本文中,您將瞭解如何使用適用於 .NET 的 Azure SDK 分頁功能,在大型數據集上有效率且具生產力地運作。 分頁是將大型數據集分割成頁面的動作,可讓取用者更輕鬆地逐一查看較小的數據量。 從 C# 8 開始,您可以使用 異步 (async) 數據流,以異步方式建立和使用數據流。 異步數據流是基於IAsyncEnumerable<T>介面的。 適用於 .NET 的 Azure SDK 會以其 IAsyncEnumerable<T> 類別公開 AsyncPageable<T> 的實作。

本文中的所有範例都依賴下列 NuGet 套件:

如需適用於 .NET 套件的 Azure SDK 最新目錄,請參閱 Azure SDK 最新版本

可分頁傳回類型

從 Azure SDK for .NET 實例化的用戶端可以傳回下列可分頁類型。

類型 說明
Pageable<T> 在頁面中擷取的值集合
AsyncPageable<T> 以異步方式在頁面中擷取的值集合

本文中的大部分範例都是使用 AsyncPageable<T> 類型的不同變化方式來實現異步的。 針對 I/O 系結作業使用異步程式設計是理想的方式。 完美的使用案例是使用適用於 .NET 的 Azure SDK 異步 API,因為這些作業代表 HTTP/S 網路呼叫。

逐一迭代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# 程式碼中:

逐一 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# 程式碼中:

使用 System.Linq.Async 搭配 AsyncPageable

System.Linq.Async 套件提供一組 LINQ 方法,這些方法可以在 類型上運作。 由於 AsyncPageable<T> 實作 IAsyncEnumerable<T>,因此您可以使用 System.Linq.Async 來查詢和轉換數據。

轉換成 List<T>

使用 ToListAsyncAsyncPageable<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# 程式碼中:

取得前 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 對應專案相等的功能。 這類方法的範例包括 SelectWhereOrderByGroupBy

注意客戶端評估

使用 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 替代專案,以取得較佳的體驗。

另請參閱