サンプル: CrmServiceClient を使用したタスク並列ライブラリ
注意
エンティティとテーブルの違いがわかりませんか? Microsoft Dataverse で「開発者: 用語を理解する」を参照してください。
タスク並列ライブラリ (TPL) は、アプリケーションに並列処理と同時実行を追加するプロセスを簡略化することで、開発者の生産性を高めます。
並列処理と同時実行性を追加すると、短期間に多数の Dataverse 操作を実行する必要があるアプリケーションの合計スループットを大幅に向上させることができます。
サンプルをダウンロードします: CrmServiceClient を使用したタスク並列ライブラリのサンプル
サンプルを実行する方法
- サンプルをダウンロードまたは抽出し、ローカル コピーを持てるようにします。
TPLCrmServiceClient.slnファイルを Visual Studio で開きます。- F5 キーを押して、プログラムをコンパイルして実行します。
説明
Microsoft.Xrm.Tooling.Connector.CrmServiceClient Class には、Dataverse サービス保護制限によってスローされる一時的なエラーの処理が含まれているため、TPL と TPL の組み合わせ CrmServiceClient は、これらの制限のために拒否された要求を再試行することにより、サービス保護制限エラーに耐性を持ちながらスループットを最適化できるアプリケーションを作成するのに役立ちます。
詳しくは:サービス保護APIの制限を参照してください。
CrmServiceClient.Clone メソッド は、TPL が複数のスレッドでクライアントを使用できるようにします。
この簡単なサンプルでは、System.Threading.Tasks.Parallel.ForEach メソッド を使用して多数のアカウント テーブル レコードを生成します。
次に、その方法を再度使用して、作成されたテーブルを削除します。
メモ:
既定では、このサンプルは 10 レコードのみを作成します。これはサービス保護 API 制限エラーにヒットするには不十分です。
numberOfRecords変数値を 10000 に上げると、Fiddler を使用して、一部の要求が拒否され再試行される方法に注意できます。
コード一覧
このサンプルのコードは、同じ部分クラスの異なる部分を定義する 2 つのファイルに分割されています。
SampleProgram.cs にはこのコードが含まれています:
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Tooling.Connector;
using System;
using System.Collections.Generic;
using System.Linq;
namespace PowerApps.Samples
{
public partial class SampleProgram
{
//How many records to create with this sample.
private static readonly int numberOfRecords = 10;
[STAThread] // Added to support UX
private static void Main()
{
#region Optimize Connection settings
//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 settings
CrmServiceClient service = null;
try
{
service = SampleHelpers.Connect("Connect");
if (service.IsReady)
{
#region Sample Code
////////////////////////////////////
#region Set up
SetUpSample(service);
#endregion Set up
#region Demonstrate
// Generate a list of account entities to create.
var accountsToImport = new List<Entity>();
var count = 0;
Console.WriteLine($"Preparing to create {numberOfRecords} acccount records");
while (count < numberOfRecords)
{
var account = new Entity("account");
account["name"] = $"Account {count}";
accountsToImport.Add(account);
count++;
}
try
{
Console.WriteLine($"Creating {accountsToImport.Count} accounts");
var startCreate = DateTime.Now;
//Import the list of accounts
var createdAccounts = CreateEntities(service, accountsToImport);
var secondsToCreate = (DateTime.Now - startCreate).TotalSeconds;
Console.WriteLine($"Created {accountsToImport.Count} accounts in {Math.Round(secondsToCreate)} seconds.");
Console.WriteLine($"Deleting {createdAccounts.Count} accounts");
var startDelete = DateTime.Now;
//Delete the list of accounts created
DeleteEntities(service, createdAccounts.ToList());
var secondsToDelete = (DateTime.Now - startDelete).TotalSeconds;
Console.WriteLine($"Deleted {createdAccounts.Count} accounts in {Math.Round(secondsToDelete)} seconds.");
}
catch (AggregateException)
{
// Handle exceptions
}
Console.WriteLine("Done.");
Console.ReadLine();
}
#endregion Demonstrate
#endregion Sample Code
else
{
const string UNABLE_TO_LOGIN_ERROR = "Unable to Login to Microsoft Dataverse";
if (service.LastCrmError.Equals(UNABLE_TO_LOGIN_ERROR))
{
Console.WriteLine("Check the connection string values in cds/App.config.");
throw new Exception(service.LastCrmError);
}
else
{
throw service.LastCrmException;
}
}
}
catch (Exception ex)
{
SampleHelpers.HandleException(ex);
}
finally
{
if (service != null)
service.Dispose();
Console.WriteLine("Press <Enter> to exit.");
Console.ReadLine();
}
}
}
}
SampleMethods.cs には、コードで使用する 2 つの静的メソッド (CreateEntities および DeleteEntities) の定義が含まれます:
/// <summary>
/// Creates entities in parallel
/// </summary>
/// <param name="svc">The CrmServiceClient instance to use</param>
/// <param name="entities">A List of entities to create.</param>
/// <returns></returns>
private static ConcurrentBag<EntityReference> CreateEntities(CrmServiceClient svc, List<Entity> entities)
{
var createdEntityReferences = new ConcurrentBag<EntityReference>();
Parallel.ForEach(entities,
new ParallelOptions() { MaxDegreeOfParallelism = svc.RecommendedDegreesOfParallelism },
() =>
{
//Clone the CrmServiceClient for each thread
return svc.Clone();
},
(entity, loopState, index, threadLocalSvc) =>
{
// In each thread, create entities and add them to the ConcurrentBag
// as EntityReferences
createdEntityReferences.Add(
new EntityReference(
entity.LogicalName,
threadLocalSvc.Create(entity)
)
);
return threadLocalSvc;
},
(threadLocalSvc) =>
{
//Dispose the cloned CrmServiceClient instance
if (threadLocalSvc != null)
{
threadLocalSvc.Dispose();
}
});
//Return the ConcurrentBag of EntityReferences
return createdEntityReferences;
}
/// <summary>
/// Deletes a list of entity references
/// </summary>
/// <param name="svc">The CrmServiceClient instance to use</param>
/// <param name="entityReferences">A List of entity references to delete.</param>
private static void DeleteEntities(CrmServiceClient svc, List<EntityReference> entityReferences)
{
Parallel.ForEach(entityReferences,
new ParallelOptions() { MaxDegreeOfParallelism = svc.RecommendedDegreesOfParallelism },
() =>
{
//Clone the CrmServiceClient for each thread
return svc.Clone();
},
(er, loopState, index, threadLocalSvc) =>
{
// In each thread, delete the entities
threadLocalSvc.Delete(er.LogicalName, er.Id);
return threadLocalSvc;
},
(threadLocalSvc) =>
{
//Dispose the cloned CrmServiceClient instance
if (threadLocalSvc != null)
{
threadLocalSvc.Dispose();
}
});
}
詳細
注意
ドキュメントの言語設定についてお聞かせください。 簡単な調査を行います。 (この調査は英語です)
この調査には約 7 分かかります。 個人データは収集されません (プライバシー ステートメント)。
フィードバック
フィードバックの送信と表示