Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reuse or create new IOrganizationService for multithreaded requests

I'm pushing a lot of data into CRM at times, like bulk updates. It is done in a workflow (CodeActivity) class, with its Execute() method. I can use the argument (the context) passed to that method to get the ServiceFactory, and then in turn create the IOrganizationService.

I then iterate a list of objects to update, change properties, and call service.Update(myObj). So far so good.

Now, to speed things up, I thought I'd run 2-4 threads that do the update in parallel.

Question 1 Should I reuse the service I just created, or create a new one, if I run two or more threads? I.e. create one service per thread, or share it?

I'm basically doing Parallel.Invoke(action1, action2, action3); where each action needs a service instance to call service.Update(myObj);

Question 2 If calling serviceFactory.CreateOrganizationService(context.UserId), will it actually create a new service, or return an existing one?

I have everything else nailed down, and it is working just fine, but wanted to get a recommendation/best practice for when multithreading within a workflow's Execute() method.

like image 384
Henrik Oscarsson Avatar asked Nov 19 '25 00:11

Henrik Oscarsson


2 Answers

I would be a little surprised if mulit-threading your application would actually improves performance (But if you can post data that says otherwise, I would love to see it)

Question 1:

The CrmOrganizationService that is used on the client side is not thread safe, I doubt the server version that implements the IOrganizationService is thread safe as well.

Question 2:

I am not aware of Microsoft specifying one way or the other, so that would lead me to believe that whatever the answer is, you can't count on it. The interface doesn't define the answer, so it could potentially be changed with the next update. With that being said, I would just test it yourself:

if(Object.ReferenceEquals(serviceFactory.CreateOrganizationService(context.UserId), serviceFactory.CreateOrganizationService(context.UserId)){
    throw new Exception("Returns the same IOrganizationService");
}

throw new Exception("Returns a new IOrganizationService");
like image 98
Daryl Avatar answered Nov 21 '25 13:11

Daryl


So, to summarize, it works just fine to run multiple threads in CRM, from within a workflow. Do this:

  1. Use the executionContext parameter passed to the Execute() method.
  2. Create an IOrganizationService like this:

IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>(); IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

Now use that service for one thread/task. If you run many threads, create one service per thread.

The other issues I had was related to a specific CRM Addon.

like image 23
Henrik Oscarsson Avatar answered Nov 21 '25 13:11

Henrik Oscarsson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!