Hi,
I am trying to use multi threading for updating a large amount of records in Dynamics 365. I am using the following code in my console app. The maximum amount of records getting updated in 2 minutes is around 2k only. But I have read in some blogs that about 100k records can be updated in 8-10 minutes.
Any help to improve the performance would be appreciated. Thanks in advance!!
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Client; using System.Net; using System.ServiceModel.Description; using Microsoft.Crm.Sdk.Messages; using Microsoft.Xrm.Sdk.Query; using Microsoft.Xrm.Sdk.Messages; using System.Diagnostics; namespace ConsoleApp { class Program { public static Stopwatch sw = new Stopwatch(); static void Main(string[] args) { try { IOrganizationService service = ConnecttoCRM(); if (service != null) { var fectXml = @" "; EntityCollection contacts = service.RetrieveMultiple(new FetchExpression(fectXml)); Console.WriteLine(contacts.Entities.Count); sw.Start(); runTask(contacts); Console.WriteLine(sw.ElapsedMilliseconds); Console.ReadLine(); } } catch(Exception ex) { Console.WriteLine(ex.Message); Console.ReadLine(); } } public static void runTask(EntityCollection contacts) { var threadCount = (int)Math.Ceiling(contacts.Entities.Count / 1000.0); ExecuteMultipleRequest requestWithResults = new ExecuteMultipleRequest() { Settings = new ExecuteMultipleSettings() { ContinueOnError = false, ReturnResponses = true }, Requests = new OrganizationRequestCollection() }; foreach (var entity in contacts.Entities) { entity["middlename"] = ""; UpdateRequest createRequest = new UpdateRequest { Target = entity }; requestWithResults.Requests.Add(createRequest); } Console.WriteLine(sw.ElapsedMilliseconds); SendMultipleRequests(requestWithResults); } public static void SendMultipleRequests(ExecuteMultipleRequest multipleRequest) { try { List tasks = new List(); int RequestLimit = 500; int RequestIndex = 0; if (multipleRequest.Requests.Count > 0) { int RemainingRequests = multipleRequest.Requests.Count / RequestLimit; while(RequestIndex < multipleRequest.Requests.Count) { ExecuteMultipleRequest request = new ExecuteMultipleRequest { Settings = new ExecuteMultipleSettings() { ContinueOnError = false, ReturnResponses = false }, // Create an empty organization request collection. Requests = new OrganizationRequestCollection(), RequestId = Guid.NewGuid() }; int limit = 0; while (limit != RequestLimit) { if (RequestIndex == multipleRequest.Requests.Count) { Console.WriteLine("Maximum Reached"); break; } request.Requests.Add(multipleRequest.Requests[RequestIndex]); RequestIndex ; // multipleRequest.Requests.RemoveAt(0); limit ; } // var v = new { ReqIndex = RequestIndex }; Task t = Task.Factory.StartNew(() => { ExecuteToCRM(request); }); tasks.Add(t); } Task.WaitAll(tasks.ToArray()); } } catch (Exception ex) { } } public static OrganizationResponse ExecuteToCRM(OrganizationRequest request) { OrganizationResponse response = new OrganizationResponse(); var service = ConnecttoCRM(); try { response = service.Execute(request); } catch (Exception ex) { Console.WriteLine(ex); } return response; } public static IOrganizationService ConnecttoCRM() { IOrganizationService service = null; String username = {username} String password = {password} // Get the URL from CRM, Navigate to Settings -> Customizations -> Developer Resources // Copy and Paste Organization Service Endpoint Address URL String url = {Organization Url} try { ClientCredentials clientCredentials = new ClientCredentials(); clientCredentials.UserName.UserName = username; clientCredentials.UserName.Password = password; // For Dynamics 365 Customer Engagement V9.X, set Security Protocol as TLS12 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; var organizationService = new OrganizationServiceProxy(new Uri(url), null, clientCredentials, null); service = (IOrganizationService)organizationService; } catch (Exception ex) { Console.WriteLine("Exception occured - " ex.Message); } return service; } } }
Hi,
There are some suggestions for your current code.
You are sending execution multiple requests in bulk to D365 which will hit the concurrent limit.
You may check the following official document.
docs.microsoft.com/.../execute-multiple-requests
Meanwhile, you may following the best practice to maximize the throughput.