【问题标题】:Using PLINQ / TPL in a custom workflow activity在自定义工作流活动中使用 PLINQ/TPL
【发布时间】:2012-09-27 03:50:59
【问题描述】:

我定义了一个工作流,当自定义实体上的字段发生更改时执行。 工作流调用一个自定义活动,该活动反过来使用 PLINQ 来处理一堆记录。 自定义活动调用的代码如下所示:

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

我注意到以下错误是一个聚合异常(InnerExceptions 中多次出现相同的错误):

“在不应该释放的时候遇到了释放的 CrmDbConnection”

根据我的阅读: CRM 2011 Workflow "Invalid Pointer" error

当您有类级别变量时可能会发生这种情况,因为工作流运行时可能会结束 跨多个工作流调用共享同一个类实例。这显然不是这里的情况,而且我没有在多个记录上运行此工作流的多个实例。在任何时间点都只运行此工作流的一个实例。

上面的代码在工作流主机 (CRMAsyncService) 之外提取和托管时可以正常工作。

这是使用 CRM 2011 Rollup 10。

非常感谢任何见解。

【问题讨论】:

  • 什么是 MyOrgserviceContext?它有什么作用?
  • O,它是来自 Linq 代码生成工具的 OrganizationServiceContext,这个名字让我大吃一惊。 (对吗?)

标签: dynamics-crm dynamics-crm-2011


【解决方案1】:

我不确定,但这可能只是因为你正在处理你的连接,ctx.Dispose()

由于每个new MyOrgservicecontext(_orgService) 对象都使用相同的IOrganizationService,我怀疑当第一个MyOrgservicecontext 被释放时,所有其他MyOrgservicecontext 对象都有一个释放连接——这意味着它们的服务调用将失败并且一个抛出异常。

我建议删除 dispose 以查看是否可以解决问题。

【讨论】:

  • James:我不会处理组织服务。我记得处置上下文并不会处置组织服务,因为组织服务可能会跨上下文共享。还要注意,每个线程创建一次上下文。每个线程可以处理多个任务,其中每个任务由主体表示Parallel.For
  • 我提出这一点的原因是,即使您创建了一个新的上下文,它们似乎都在使用相同的服务,我通常希望调用 dispose 来清除该服务。正如我所说,我不确定,但我认为这可能值得一试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多