Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Microsoft.Xrm.Tooling.Connector High Memory Allocation

I am currently going through the process of upgrading our product CRM SDK and the main change I have encountered is that instead of connecting to the Xrm service and creating my IOrganizationService using the tried and trusted method of:

var connection = CrmConnection.Parse(connectionString);
var service = new OrganizationService(connection);

I am now having to utilise the CrmServiceClient from the Tooling namespace:

 CrmServiceClient conn = new Microsoft.Xrm.Tooling.Connector.CrmServiceClient(connectionString).OrganizationServiceProxy;

Now this is all fine except from one major issue...memory.

Using the older Xrm.Client method you were able to specify the Service Configuration Instance Mode (which defaulted to ServiceConfigurationInstanceMode.PerName). What this meant is that the service was reused if the same application called the create multiple times. This kept the memory footprint low. The below image show the amount of allocated memory after calling to create a service instance 100 times

enter image description here

However, using the newer method you cannot set this instance mode anywhere and it seems that a brand new connection is created every time whether you want it or not. Here are the results of the same test: enter image description here

As you can see, with every new connection, more and more memory is allocated. I can;t see anywhere that i can tell it to reuse the service.

So what I'm basically asking is, am I going about this in the wrong way? Should I be creating and caching everything myself? Are there hidden classes/methods that I am missing? Any help would be greatly appreciated.

like image 622
doodlleus Avatar asked Nov 09 '22 05:11

doodlleus


1 Answers

The latest SDK (8.2.0.1) caches and resuses the connection as long as the connectionstring does not inclue RequireNewInstance=true.

One thing worth noting is even if you new up another CrmServiceClientwith a unique connection string (pointing to a different CRM organization), but the connection string does not include RequireNewInstance=true, the CrmServiceClient will reuse the previous cached connection.

So

var connectionString = $@"Url=https://ORG1.crm.dynamics.com;AuthType=Office365;[email protected];Password=PASSWORD";
var connectionString2 = $@"Url=https://ORG2.crm.dynamics.com;AuthType=Office365;[email protected];Password=PASSWORD";       

var crmSvcClient = new CrmServiceClient(connectionString);
((WhoAmIResponse)crmSvcClient.Execute(new WhoAmIRequest())).OrganizationId.Dump();
crmSvcClient.ConnectedOrgFriendlyName.Dump();

var crmSvcClient2 = new CrmServiceClient(connectionString2);
((WhoAmIResponse)crmSvcClient2.Execute(new WhoAmIRequest())).OrganizationId.Dump();
crmSvcClient2.ConnectedOrgFriendlyName.Dump();

Prints out the guid and ORG1 friendly name both times. If you pass RequireNewInstance=true in connectionstring2 then you will see ORG2 printed out.

like image 90
Matt Dearing Avatar answered Nov 15 '22 07:11

Matt Dearing