Web API CDSWebApiService の非同期並列操作のサンプル (C#)
注意
エンティティとテーブルの違いがわかりませんか? Microsoft Dataverse で「開発者: 用語を理解する」を参照してください。
このサンプルは、非同期要求でタスク並列ライブラリ (TPL) データフロー コンポーネント データフロー (タスク並列ライブラリ) を使用する方法を示しています。
TPL は、アプリケーションに並列処理と同時実行を追加する機能を提供します。 これらの機能は、Dataverse 内でデータを追加または更新する操作を実行する際に、スループットを最大化するための重要な役割を果たします。
このサンプルでは、非同期操作内で CDSWebApiService クラスの非同期メソッドを使用します。 CDSWebApiService クラスは、Service Protection API の制限を管理できるため、このコードは、クライアントが予期する一時的な 429 エラーに対して回復性があります。 構成可能な回数再試行します。 詳しくは:サービス保護APIの制限を参照してください。
このサンプルでは、構成可能な数のアカウント行 (レコード) を作成と構成、削除をします。 このサンプルでは、データフローのコンポーネントを使用して行を処理し、作成操作の結果を、これらの行を削除する次のフェーズに変換します。 このデータフローの性質上、先に作成した行の削除操作は、作成する行がすべて終了する前に開始します。
前提条件
以下は CDSWebApiService C# サンプルの構築および実行に必要です。
- Microsoft Visual Studio 2019。
- CRUD 操作を実行する特権を用いて Microsoft Dataverse にアクセスします。
このサンプルを実行する方法
PowerApps - サンプル GitHub リポジトリに移動して、サンプル リポジトリをクローンもしくはダウンロードし、ローカル フォルダに内容を解凍してください。
リポジトリ フォルダ cds/webapi/C#/AsyncParallelOperations に移動し、Visual Studio で AsyncParallelOperations.sln ファイルを開きます。
ソリューション エクスプローラー の AsyncParallelOperations プロジェクトで、App.config ファイルを開きます。 これは、すべての Web API C# サンプルで使用される共有アプリケーション構成ファイルです。 このファイルを編集した後は、サンプルの実行に使用する環境またはログオンを変更しない限り、ファイルを再編集する必要はありません。
Url、UserPrincipalName、とPasswordの値を編集して、接続する Dataverse インスタンスと資格情報を設定する必要があります。<add name="Connect" connectionString="Url=https://yourorg.api.crm.dynamics.com; Authority=null; ClientId=51f81489-12ee-4a9e-aaae-a2591f45987d; RedirectUrl=app://58145B91-0C36-4500-8554-080854F2AC97; UserPrincipalName=you@yourorg.onmicrosoft.com; Password=y0urp455w0rd; CallerObjectId=null; Version=9.1; MaxRetries=3; TimeoutInSeconds=180; "/>AsyncParallelOperations プロジェクトがスタートアップ プロジェクトとして設定されていることを確認します。 プロジェクトの名前は、スタートアップ プロジェクトであることを示すために太字にする必要があります。 名前が太字でない場合は、ソリューション エクスプローラーでその名前を右クリックして、スタートアップ プロジェクトに設定 を選択します。
F5 キーを押して、プログラムをデバッグ モードで実行します。
コード一覧
このサンプルは、CDSWebAPIService プロジェクトに含まれているアセンブリに依存しています。 このクラスが提供するメソッドについては、Web API CDSWebApiService クラス サンプル (C#) を参照してください。
以下は、Program.cs ファイルのコードです。
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
namespace PowerApps.Samples
{
internal class Program
{
//Get configuration data from App.config connectionStrings
private static readonly string connectionString = ConfigurationManager.ConnectionStrings["Connect"].ConnectionString;
private static readonly ServiceConfig serviceConfig = new ServiceConfig(connectionString);
//Controls the max degree of parallelism
private static readonly int maxDegreeOfParallelism = 10;
//How many records to create with this sample.
private static readonly int numberOfRecords = 100;
private static async Task Main()
{
#region Optimize Connection
//Change max connections from .NET to a remote service default: 2
System.Net.ServicePointManager.DefaultConnectionLimit = 65000;
//Bump up the min threads reserved for this app to ramp connections faster - minWorkerThreads defaults to 4, minIOCP defaults to 4
System.Threading.ThreadPool.SetMinThreads(100, 100);
//Turn off the Expect 100 to continue message - 'true' will cause the caller to wait until it round-trip confirms a connection to the server
System.Net.ServicePointManager.Expect100Continue = false;
//Can decrease overall transmission overhead but can cause delay in data packet arrival
System.Net.ServicePointManager.UseNagleAlgorithm = false;
#endregion Optimize Connection
var executionDataflowBlockOptions = new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = maxDegreeOfParallelism
};
var count = 0;
double secondsToComplete;
//Will be populated with account records to import
List<JObject> accountsToImport = new List<JObject>();
Console.WriteLine($"Preparing to create {numberOfRecords} acccount records using Web API.");
//Add account records to the list to import
while (count < numberOfRecords)
{
var account = new JObject
{
["name"] = $"Account {count}"
};
accountsToImport.Add(account);
count++;
}
using (var svc = new CDSWebApiService(serviceConfig))
{
secondsToComplete = await ProcessData(svc, accountsToImport, executionDataflowBlockOptions);
}
Console.WriteLine($"Created and deleted {accountsToImport.Count} accounts in {Math.Round(secondsToComplete)} seconds.");
Console.WriteLine("Sample completed. Press any key to exit.");
Console.ReadLine();
}
private static async Task<double> ProcessData(CDSWebApiService svc, List<JObject> accountsToImport,
ExecutionDataflowBlockOptions executionDataflowBlockOptions)
{
var createAccounts = new TransformBlock<JObject, Uri>(
async a =>
{
return await svc.PostCreateAsync("accounts", a);
},
executionDataflowBlockOptions
);
var deleteAccounts = new ActionBlock<Uri>(
async u =>
{
await svc.DeleteAsync(u);
},
executionDataflowBlockOptions
);
createAccounts.LinkTo(deleteAccounts, new DataflowLinkOptions { PropagateCompletion = true });
var start = DateTime.Now;
accountsToImport.ForEach(a => createAccounts.SendAsync(a));
createAccounts.Complete();
await deleteAccounts.Completion;
//Calculate the duration to complete
return (DateTime.Now - start).TotalSeconds;
}
}
}
関連項目
Dataverse Web API を使用する
Web API CDSWebApiService クラス サンプル (C#)
Web API CDSWebApiService の基本操作のサンプル (C#)
Web API CDSWebApiService の並列操作のサンプル (C#)
Web API を使用してテーブルを作成する
Web API を使用したテーブル行の更新と削除
注意
ドキュメントの言語設定についてお聞かせください。 簡単な調査を行います。 (この調査は英語です)
この調査には約 7 分かかります。 個人データは収集されません (プライバシー ステートメント)。
フィードバック
フィードバックの送信と表示