【C#】【Dynamics CRM】Parallel.Forによる並列処理
前回Dynamics CRMのExecuteMultipleRequestによる一括実行を書き留めましたが、今回は.netの並列処理の1つであるParallel.For処理方法を記載してみたいと思います。
詳しくはやっぱりDynamics CRM team Blogで実践されてますが、ここはやっぱり自分でも試して実感してみたいということで。
概要
Blogでも紹介されていますが、Dynamics CRMと連携した並列処理を効果的に実践するには各スレッドごとにIServiceManagementを利用したOrganizationServiceProxyを生成し、処理をする方法になる模様です。
過去のBlogでは、CrmConnectionを利用しOrganizationServiceの生成を行っていましたが、今回はOrganizationServiceProxyの方を利用します。
■実施環境 Dynamics CRM Online 2015 SDK 7.0
OrganizationServiceProxyの生成
Uri serviceUri = new Uri("https://XXX.api.crm7.dynamics.com/XRMServices/2011/Organization.svc"); IServiceManagement<IOrganizationService> orgServiceManagement = ServiceConfigurationFactory.CreateManagement<IOrganizationService>(serviceUri); ClientCredentials clientCredentials = new ClientCredentials(); clientCredentials.UserName.UserName = "XXX@XXX.onmicrosoft.com"; clientCredentials.UserName.Password = "XXXXXX"; AuthenticationCredentials authCredentials = orgServiceManagement.Authenticate(new AuthenticationCredentials() { ClientCredentials = clientCredentials }); OrganizationServiceProxy serviceProxy = new OrganizationServiceProxy(orgServiceManagement, authCredentials.SecurityTokenResponse)
ちなみにCrmConnectionを利用した【OrganizationServiceProxy】の生成方法は下のBlogで紹介されていました。
Parallel.Forでの並列Createの実施
以下のような感じで、Parallel.For内部で、OrganizationServiceProxyの生成を行い、どんどんレコードを作成していく感じです。
ちなみに、試しに今回Parallel.Forにオプションとして、上限スレッド数を指定しませんでした。
そうして実行したところスレッド数は120ほどまで上昇。 CreateのI/Oないし、OrganizationServiceProxyの生成待ち、でここまで作成された感じです。
自分のPCの性能が i7-3770 3.40GHz(8コア)なのですが、CPUは20%くらいでほとんど使用していませんでした。ここからも、Dynamics CRM 組織サービスの方に負荷がかかっていたのではないのかなぁと思えます。
/// <summary> /// /// </summary> /// <param name="orgServiceManagement"></param> /// <param name="authCredentials"></param> private static void CreatePrallelFor(IServiceManagement<IOrganizationService> orgServiceManagement, AuthenticationCredentials authCredentials) { Parallel.For(0, 100, i => { using (OrganizationServiceProxy serviceProxy = new OrganizationServiceProxy(orgServiceManagement, authCredentials.SecurityTokenResponse)) { Entity account = new Entity("account"); for (int j = 0; j < 100; j++) { account["name"] = string.Format("Parallel For : Thread {0} : Count {1}", i, j); serviceProxy.Create(account); } } }); Console.WriteLine("End Create Nomal " + sw.Elapsed); }
実行結果として以下の様な感じになっています。
次回、通常方法、Parallel方法、Parallel&ExecuteMultipleRequest方法での実行結果を比較してみたいと思います。