0

I have a workflow defined to execute when a field on a custom entity is changed. The workflow calls into a custom activity which in turn uses PLINQ to process a bunch of records. The code that the custom activty calls into looks like so:

protected override void Execute(CodeActivityContext executionContext)
{
  // Get the context service.
  IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();
  IOrganizationServiceFactory serviceFactory =     
  executionContext.GetExtension<IOrganizationServiceFactory>();
 // Use the context service to create an instance of IOrganizationService.
 IOrganizationService _orgService = serviceFactory.CreateOrganizationService  
 (context.InitiatingUserId);
     int pagesize = 2000;
     // use FetchXML aggregate functions to get total count of the number of record to process
     // Reference: http://msdn.microsoft.com/en-us/library/gg309565.aspx
     int totalcount = GetTotalCount();

   int totalPages = (int)Math.Ceiling((double)totalcount / (double)pagesize);           
    try
     {
         Parallel.For(1, 
                     totalPages + 1, 
                    () => new MyOrgserviceContext(_orgService), 
            (pageIndex, state, ctx) =>
             {

                var items = ctx.myEntitySet.Skip((pageIndex - 1) * pagesize).Take(pagesize);
                 foreach(var item in items)
                {
                    //process item as needed 
                   ctx.SaveChanges();
                }
                 return ctx;
             },
             ctx => ctx.Dispose()
             );
     }
     catch (AggregateException ex)
     {
        //handle as needed
     }
 }

I'm noticing the following error(s) as an aggregate exception (multiple occurences of the same error in the InnerExceptions):

"Encountered disposed CrmDbConnection when it should not be disposed"

From what I've read: CRM 2011 Workflow "Invalid Pointer" error

this can happen when you have class level variables since the workflow runtime can end up sharing the same class instance across multiple workflow invocations. This is clearly not the case here and also I don't have multiple instances of this workflow running on multiple records. There is just one instance of this workflow running at any point in time.

The code above works fine when extracted and hosted outside the workflow host (CRMAsyncService).

This is using CRM 2011 Rollup 10.

Any insights much appreciated.

Community
  • 1
  • 1
Abhijeet Patel
  • 6,562
  • 8
  • 50
  • 93

1 Answers1

0

I'm not certain, but this might just because you are disposing of your connection, at ctx.Dispose().

As each new MyOrgservicecontext(_orgService) object uses the same IOrganizationService, I would suspect when the first MyOrgservicecontext is disposed, then all the other MyOrgservicecontext objects then have a disposed connection - meaning their service calls will fail and an exception is throw.

I would suggest removing the dispose to see if this resolves the problem.

James Wood
  • 17,286
  • 4
  • 46
  • 89
  • James:I'm not disposing the org service. I recall that disposing the context does not dispose the org service for the very reason that the orgservice might be shared across contexts.Also note that the context is created once per thread.Each thread can process multiple tasks where each task is represented by the body of the Parallel.For – Abhijeet Patel Sep 26 '12 at 20:51
  • The reason I raised the point is that even though you create a new context they are all appear to be using the same service, and I would generally expect a dispose call to clear up the service. As I said, I'm not certain, but I thought it might have been worth a shot. – James Wood Sep 26 '12 at 21:25