Morning Girl

Web API, Windows, C#, .NET, Dynamics 365/CRM etc..

【C#】【Dynamics CRM】Parallel.Forによる並列処理

前回Dynamics CRMのExecuteMultipleRequestによる一括実行を書き留めましたが、今回は.netの並列処理の1つであるParallel.For処理方法を記載してみたいと思います。

詳しくはやっぱりDynamics CRM team Blogで実践されてますが、ここはやっぱり自分でも試して実感してみたいということで。

blogs.msdn.com

概要

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で紹介されていました。

outofmem.hatenablog.com

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);
        }

実行結果として以下の様な感じになっています。

f:id:sugimomoto:20150409143700p:plain

次回、通常方法、Parallel方法、Parallel&ExecuteMultipleRequest方法での実行結果を比較してみたいと思います。